diff --git a/docs/data/date-pickers/custom-layout/AddComponent.js b/docs/data/date-pickers/custom-layout/AddComponent.js index e2c6f46043057..d6e0d1db8b6fe 100644 --- a/docs/data/date-pickers/custom-layout/AddComponent.js +++ b/docs/data/date-pickers/custom-layout/AddComponent.js @@ -1,4 +1,5 @@ import * as React from 'react'; + import Box from '@mui/material/Box'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; diff --git a/docs/data/date-pickers/custom-layout/AddComponent.tsx b/docs/data/date-pickers/custom-layout/AddComponent.tsx index 4a519d02f7909..2584a13756edf 100644 --- a/docs/data/date-pickers/custom-layout/AddComponent.tsx +++ b/docs/data/date-pickers/custom-layout/AddComponent.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Dayjs } from 'dayjs'; import Box from '@mui/material/Box'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; @@ -57,7 +58,7 @@ function RestaurantHeader() { ); } -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { toolbar, tabs, content, actionBar } = usePickerLayout(props); return ( diff --git a/docs/data/date-pickers/date-range-picker/BasicRangeShortcuts.tsx b/docs/data/date-pickers/date-range-picker/BasicRangeShortcuts.tsx index 542449ecbd806..765d9e982a81b 100644 --- a/docs/data/date-pickers/date-range-picker/BasicRangeShortcuts.tsx +++ b/docs/data/date-pickers/date-range-picker/BasicRangeShortcuts.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { diff --git a/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.js b/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.js index ab660eb554b93..e102430740bdc 100644 --- a/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.js +++ b/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.js @@ -1,4 +1,5 @@ import * as React from 'react'; + import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; diff --git a/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.tsx b/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.tsx index 745dc885db66c..6465a9a84a039 100644 --- a/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.tsx +++ b/docs/data/date-pickers/fields/ControlledSelectedSectionsSingleInputRangeField.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Dayjs } from 'dayjs'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; @@ -9,14 +10,14 @@ import { FieldSelectedSections, FieldRef, } from '@mui/x-date-pickers/models'; -import { RangePosition } from '@mui/x-date-pickers-pro/models'; +import { DateRange, RangePosition } from '@mui/x-date-pickers-pro/models'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; export default function ControlledSelectedSectionsSingleInputRangeField() { const [selectedSections, setSelectedSections] = React.useState(null); const inputRef = React.useRef(null); - const fieldRef = React.useRef>(null); + const fieldRef = React.useRef>>(null); const setSelectedSectionType = ( selectedSectionType: FieldSectionType, diff --git a/docs/data/date-pickers/shortcuts/AdvancedRangeShortcuts.tsx b/docs/data/date-pickers/shortcuts/AdvancedRangeShortcuts.tsx index b9a10aac26234..0cd7c557d3a8b 100644 --- a/docs/data/date-pickers/shortcuts/AdvancedRangeShortcuts.tsx +++ b/docs/data/date-pickers/shortcuts/AdvancedRangeShortcuts.tsx @@ -4,8 +4,9 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'Next Available Weekend', getValue: ({ isValid }) => { diff --git a/docs/data/date-pickers/shortcuts/BasicRangeShortcuts.tsx b/docs/data/date-pickers/shortcuts/BasicRangeShortcuts.tsx index fddda2042f82b..6c63788ef095b 100644 --- a/docs/data/date-pickers/shortcuts/BasicRangeShortcuts.tsx +++ b/docs/data/date-pickers/shortcuts/BasicRangeShortcuts.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { diff --git a/docs/data/date-pickers/shortcuts/BasicShortcuts.tsx b/docs/data/date-pickers/shortcuts/BasicShortcuts.tsx index 3545b5bac0a5b..3ce1d19e79669 100644 --- a/docs/data/date-pickers/shortcuts/BasicShortcuts.tsx +++ b/docs/data/date-pickers/shortcuts/BasicShortcuts.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; @@ -24,7 +24,7 @@ const getMonthWeekday = ( ); }; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem[] = [ { label: "New Year's Day", getValue: () => { diff --git a/docs/data/date-pickers/shortcuts/ChangeImportance.tsx b/docs/data/date-pickers/shortcuts/ChangeImportance.tsx index a147a9b74c467..5ef6c1e18d3eb 100644 --- a/docs/data/date-pickers/shortcuts/ChangeImportance.tsx +++ b/docs/data/date-pickers/shortcuts/ChangeImportance.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; @@ -30,7 +30,7 @@ const getMonthWeekday = ( ); }; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem[] = [ { label: "New Year's Day", getValue: () => { diff --git a/docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.tsx b/docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.tsx index fc2170ffbd298..87530990c3a87 100644 --- a/docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.tsx +++ b/docs/data/date-pickers/shortcuts/CustomizedRangeShortcuts.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import Chip from '@mui/material/Chip'; @@ -12,8 +12,9 @@ import { PickersShortcutsItem, PickersShortcutsProps, } from '@mui/x-date-pickers/PickersShortcuts'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { @@ -54,7 +55,7 @@ const shortcutsItems: PickersShortcutsItem[] = [ { label: 'Reset', getValue: () => [null, null] }, ]; -function CustomRangeShortcuts(props: PickersShortcutsProps) { +function CustomRangeShortcuts(props: PickersShortcutsProps>) { const { items, onChange, isValid, changeImportance = 'accept' } = props; if (items == null || items.length === 0) { diff --git a/docs/data/date-pickers/shortcuts/DisabledDatesShortcuts.tsx b/docs/data/date-pickers/shortcuts/DisabledDatesShortcuts.tsx index ab851fd9258b1..e6224b5598518 100644 --- a/docs/data/date-pickers/shortcuts/DisabledDatesShortcuts.tsx +++ b/docs/data/date-pickers/shortcuts/DisabledDatesShortcuts.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; @@ -24,7 +24,7 @@ const getMonthWeekday = ( ); }; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem[] = [ { label: "New Year's Day", getValue: () => { diff --git a/docs/data/date-pickers/shortcuts/OnChangeShortcutLabel.tsx b/docs/data/date-pickers/shortcuts/OnChangeShortcutLabel.tsx index 56b9c54f33c01..bb52431010499 100644 --- a/docs/data/date-pickers/shortcuts/OnChangeShortcutLabel.tsx +++ b/docs/data/date-pickers/shortcuts/OnChangeShortcutLabel.tsx @@ -32,7 +32,7 @@ const getMonthWeekday = ( ); }; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem[] = [ { label: "New Year's Day", getValue: () => { diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js index 502bdd7ec9c09..95819b45ed99f 100644 --- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js +++ b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.js @@ -1,4 +1,5 @@ import * as React from 'react'; + import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import IconButton from '@mui/material/IconButton'; diff --git a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx index 8a8b7511afb39..97a25bbfc0363 100644 --- a/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx +++ b/docs/data/migration/migration-pickers-v5/MobileKeyboardView.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Dayjs } from 'dayjs'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import IconButton from '@mui/material/IconButton'; @@ -21,7 +22,7 @@ import { DatePickerToolbarProps, } from '@mui/x-date-pickers/DatePicker'; -function LayoutWithKeyboardView(props: PickersLayoutProps) { +function LayoutWithKeyboardView(props: PickersLayoutProps) { const { value, onChange } = props; const [showKeyboardView, setShowKeyboardView] = React.useState(false); diff --git a/docs/pages/x/api/date-pickers/date-calendar.json b/docs/pages/x/api/date-pickers/date-calendar.json index 51c6444ec1640..e38e7f86edc4c 100644 --- a/docs/pages/x/api/date-pickers/date-calendar.json +++ b/docs/pages/x/api/date-pickers/date-calendar.json @@ -34,7 +34,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", + "type": "function(value: TValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", "describedArgs": ["value", "selectionState", "selectedView"] } }, diff --git a/docs/pages/x/api/date-pickers/date-field.json b/docs/pages/x/api/date-pickers/date-field.json index 70a5d85c1ab25..6a53307f3dc31 100644 --- a/docs/pages/x/api/date-pickers/date-field.json +++ b/docs/pages/x/api/date-pickers/date-field.json @@ -42,7 +42,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -50,7 +50,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/date-picker.json b/docs/pages/x/api/date-pickers/date-picker.json index 7b7b27290afee..e27298dacae1d 100644 --- a/docs/pages/x/api/date-pickers/date-picker.json +++ b/docs/pages/x/api/date-pickers/date-picker.json @@ -45,14 +45,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -60,7 +60,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/date-range-calendar.json b/docs/pages/x/api/date-pickers/date-range-calendar.json index 6bf85b33aa76a..c8273a8875669 100644 --- a/docs/pages/x/api/date-pickers/date-range-calendar.json +++ b/docs/pages/x/api/date-pickers/date-range-calendar.json @@ -43,7 +43,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", + "type": "function(value: TValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", "describedArgs": ["value", "selectionState", "selectedView"] } }, diff --git a/docs/pages/x/api/date-pickers/date-range-picker.json b/docs/pages/x/api/date-pickers/date-range-picker.json index 80c20357f818a..9ee6734f43842 100644 --- a/docs/pages/x/api/date-pickers/date-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-range-picker.json @@ -55,14 +55,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -70,7 +70,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/date-time-field.json b/docs/pages/x/api/date-pickers/date-time-field.json index 902607f0b4bd8..8ddb6b01c5cc3 100644 --- a/docs/pages/x/api/date-pickers/date-time-field.json +++ b/docs/pages/x/api/date-pickers/date-time-field.json @@ -49,7 +49,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -57,7 +57,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/date-time-picker.json b/docs/pages/x/api/date-pickers/date-time-picker.json index ce1823f6ce4f9..b2443301cad98 100644 --- a/docs/pages/x/api/date-pickers/date-time-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-picker.json @@ -53,14 +53,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -68,7 +68,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/date-time-range-picker.json b/docs/pages/x/api/date-pickers/date-time-range-picker.json index 59e088e5d2807..add2fd7dede45 100644 --- a/docs/pages/x/api/date-pickers/date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/date-time-range-picker.json @@ -62,14 +62,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -77,7 +77,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/desktop-date-picker.json b/docs/pages/x/api/date-pickers/desktop-date-picker.json index cbe53bb4fe238..1418cf907e00a 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-picker.json @@ -41,14 +41,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -56,7 +56,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json index 64329dc404818..23fd6ab658165 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-range-picker.json @@ -51,14 +51,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -66,7 +66,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json index 08acff4c444d8..98a3cad44b438 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-picker.json @@ -49,14 +49,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -64,7 +64,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json index 3cd1b911bece8..6706455ebb5b6 100644 --- a/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-date-time-range-picker.json @@ -58,14 +58,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -73,7 +73,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/desktop-time-picker.json b/docs/pages/x/api/date-pickers/desktop-time-picker.json index 6bd4992c9ce64..d372b04bdfc0f 100644 --- a/docs/pages/x/api/date-pickers/desktop-time-picker.json +++ b/docs/pages/x/api/date-pickers/desktop-time-picker.json @@ -28,14 +28,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -43,7 +43,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/digital-clock.json b/docs/pages/x/api/date-pickers/digital-clock.json index a18b2ace56c77..1d06e31bfb380 100644 --- a/docs/pages/x/api/date-pickers/digital-clock.json +++ b/docs/pages/x/api/date-pickers/digital-clock.json @@ -15,7 +15,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", + "type": "function(value: TValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", "describedArgs": ["value", "selectionState", "selectedView"] } }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-picker.json b/docs/pages/x/api/date-pickers/mobile-date-picker.json index f1c1c3fa98469..37e3b9e9be0b8 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-picker.json @@ -41,14 +41,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -56,7 +56,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json index 6f45cc30f39fd..82670cc2d753e 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-range-picker.json @@ -47,14 +47,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -62,7 +62,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json index 8279db1828a3c..23adb960d841c 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-picker.json @@ -49,14 +49,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -64,7 +64,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json index 560915cf7b4bd..32e3b7676d7d8 100644 --- a/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-date-time-range-picker.json @@ -54,14 +54,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -69,7 +69,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/mobile-time-picker.json b/docs/pages/x/api/date-pickers/mobile-time-picker.json index c0c818dd9208e..c3898c0d4a927 100644 --- a/docs/pages/x/api/date-pickers/mobile-time-picker.json +++ b/docs/pages/x/api/date-pickers/mobile-time-picker.json @@ -28,14 +28,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -43,7 +43,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json index 2c4e917acab53..d9e6f2cbf77d5 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-range-field.json @@ -25,14 +25,14 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json index 5d8c4fc3e8957..783e9b93b4674 100644 --- a/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-date-time-range-field.json @@ -32,14 +32,14 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json index 25b17636d1fec..120e10742bd03 100644 --- a/docs/pages/x/api/date-pickers/multi-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/multi-input-time-range-field.json @@ -28,14 +28,14 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json index 2789cb593ce70..d2b097c5e7635 100644 --- a/docs/pages/x/api/date-pickers/multi-section-digital-clock.json +++ b/docs/pages/x/api/date-pickers/multi-section-digital-clock.json @@ -20,7 +20,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", + "type": "function(value: TValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", "describedArgs": ["value", "selectionState", "selectedView"] } }, diff --git a/docs/pages/x/api/date-pickers/single-input-date-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-range-field.json index 958a4ac0a4e33..179b58765222e 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-range-field.json @@ -43,7 +43,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -51,7 +51,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json index 872b76d0f00be..483f9c0016493 100644 --- a/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-date-time-range-field.json @@ -50,7 +50,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -58,7 +58,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/single-input-time-range-field.json b/docs/pages/x/api/date-pickers/single-input-time-range-field.json index 98339e02b0123..fbfcdcd2781ec 100644 --- a/docs/pages/x/api/date-pickers/single-input-time-range-field.json +++ b/docs/pages/x/api/date-pickers/single-input-time-range-field.json @@ -46,7 +46,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -54,7 +54,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/static-date-picker.json b/docs/pages/x/api/date-pickers/static-date-picker.json index a1f77f36f12ec..2c656b2b01cb2 100644 --- a/docs/pages/x/api/date-pickers/static-date-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-picker.json @@ -32,14 +32,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -51,7 +51,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/static-date-range-picker.json b/docs/pages/x/api/date-pickers/static-date-range-picker.json index 9b55410b01e36..5dace702ff425 100644 --- a/docs/pages/x/api/date-pickers/static-date-range-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-range-picker.json @@ -42,14 +42,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -61,7 +61,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/static-date-time-picker.json b/docs/pages/x/api/date-pickers/static-date-time-picker.json index 2f26cd38a3439..e265e0d208c11 100644 --- a/docs/pages/x/api/date-pickers/static-date-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-date-time-picker.json @@ -40,14 +40,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -59,7 +59,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/static-time-picker.json b/docs/pages/x/api/date-pickers/static-time-picker.json index 3a416080312f8..2e9251b190fca 100644 --- a/docs/pages/x/api/date-pickers/static-time-picker.json +++ b/docs/pages/x/api/date-pickers/static-time-picker.json @@ -19,14 +19,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -38,7 +38,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/time-clock.json b/docs/pages/x/api/date-pickers/time-clock.json index c634a59038af6..2b59bb35d2d46 100644 --- a/docs/pages/x/api/date-pickers/time-clock.json +++ b/docs/pages/x/api/date-pickers/time-clock.json @@ -21,7 +21,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", + "type": "function(value: TValue, selectionState: PickerSelectionState | undefined, selectedView: TView | undefined) => void", "describedArgs": ["value", "selectionState", "selectedView"] } }, diff --git a/docs/pages/x/api/date-pickers/time-field.json b/docs/pages/x/api/date-pickers/time-field.json index 1c0dd01f9f320..fb99ace144ee2 100644 --- a/docs/pages/x/api/date-pickers/time-field.json +++ b/docs/pages/x/api/date-pickers/time-field.json @@ -45,7 +45,7 @@ "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -53,7 +53,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/pages/x/api/date-pickers/time-picker.json b/docs/pages/x/api/date-pickers/time-picker.json index 19f52eff4cc3d..66c11b29ef3e0 100644 --- a/docs/pages/x/api/date-pickers/time-picker.json +++ b/docs/pages/x/api/date-pickers/time-picker.json @@ -32,14 +32,14 @@ "onAccept": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, "onChange": { "type": { "name": "func" }, "signature": { - "type": "function(value: InferPickerValue, context: FieldChangeHandlerContext) => void", + "type": "function(value: TValue, context: FieldChangeHandlerContext) => void", "describedArgs": ["value", "context"] } }, @@ -47,7 +47,7 @@ "onError": { "type": { "name": "func" }, "signature": { - "type": "function(error: TError, value: InferPickerValue) => void", + "type": "function(error: TError, value: TValue) => void", "describedArgs": ["error", "value"] } }, diff --git a/docs/src/modules/components/PickersPlayground.tsx b/docs/src/modules/components/PickersPlayground.tsx index 188921e6e3e93..7366b804e1847 100644 --- a/docs/src/modules/components/PickersPlayground.tsx +++ b/docs/src/modules/components/PickersPlayground.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { alpha, styled } from '@mui/material/styles'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import Box from '@mui/material/Box'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; @@ -33,6 +33,7 @@ import { } from '@mui/x-date-pickers/StaticDateTimePicker'; import { DateOrTimeView } from '@mui/x-date-pickers/models'; import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { MobileDateRangePicker } from '@mui/x-date-pickers-pro/MobileDateRangePicker'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; @@ -175,7 +176,7 @@ interface ComponentFamilySet { props: Record; } -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { diff --git a/docs/src/modules/components/overview/mainDemo/Clock.tsx b/docs/src/modules/components/overview/mainDemo/Clock.tsx index 75d467ebf5b72..6ca16f44532e0 100644 --- a/docs/src/modules/components/overview/mainDemo/Clock.tsx +++ b/docs/src/modules/components/overview/mainDemo/Clock.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { styled } from '@mui/material/styles'; import Card from '@mui/material/Card'; import { StaticTimePicker } from '@mui/x-date-pickers/StaticTimePicker'; @@ -31,7 +31,7 @@ const StyledLayout = styled(PickersLayoutRoot)({ }, }); -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { actionBar, content, toolbar } = usePickerLayout(props); return ( diff --git a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx index 734ddaea4a754..c8a9df4ce611c 100644 --- a/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx +++ b/docs/src/modules/components/overview/mainDemo/DateRangeWithShortcuts.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import dayjs from 'dayjs'; +import dayjs, { Dayjs } from 'dayjs'; import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; import Card from '@mui/material/Card'; @@ -12,8 +12,9 @@ import { PickersLayoutRoot, PickersLayoutContentWrapper, } from '@mui/x-date-pickers/PickersLayout'; +import { DateRange } from '@mui/x-date-pickers-pro/models'; -const shortcutsItems: PickersShortcutsItem[] = [ +const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { @@ -54,7 +55,7 @@ const shortcutsItems: PickersShortcutsItem[] = [ { label: 'Reset', getValue: () => [null, null] }, ]; -interface CustomLayoutProps extends PickersLayoutProps { +interface CustomLayoutProps extends PickersLayoutProps, 'day'> { isHorizontal?: boolean; } function CustomLayout(props: CustomLayoutProps) { diff --git a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx index 75fa5a6586826..b6959d39ed3f4 100644 --- a/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx +++ b/docs/src/modules/components/overview/mainDemo/DigitalClock.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { Dayjs } from 'dayjs'; import { styled } from '@mui/material/styles'; import Card from '@mui/material/Card'; import Paper from '@mui/material/Paper'; @@ -23,7 +24,7 @@ const StyledLayout = styled(PickersLayoutRoot)({ }, }); -function CustomLayout(props: PickersLayoutProps) { +function CustomLayout(props: PickersLayoutProps) { const { actionBar, content } = usePickerLayout(props); return ( diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx index 3a4135e7b4d3d..6c6379c2b433d 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.tsx @@ -215,7 +215,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( } = props; const { value, handleValueChange, timezone } = useControlledValueWithTimezone< - true, + PickerRangeValue, NonNullable >({ name: 'DateRangeCalendar', @@ -226,7 +226,7 @@ const DateRangeCalendar = React.forwardRef(function DateRangeCalendar( valueManager: rangeValueManager, }); - const { setValueAndGoToNextView, view } = useViews({ + const { setValueAndGoToNextView, view } = useViews({ view: inView, views, openTo, @@ -718,9 +718,9 @@ DateRangeCalendar.propTypes = { minDate: PropTypes.object, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ diff --git a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts index ca369afa41e31..daf02127d032b 100644 --- a/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangeCalendar/DateRangeCalendar.types.ts @@ -93,7 +93,7 @@ export interface ExportedDateRangeCalendarProps export interface DateRangeCalendarProps extends ExportedDateRangeCalendarProps, UseRangePositionProps, - ExportedUseViewsOptions { + ExportedUseViewsOptions { /** * The selected value. * Used when the component is controlled. diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx index 6d3d87856f63f..76bb9c9804dff 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx @@ -193,17 +193,17 @@ DateRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -217,9 +217,9 @@ DateRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts index 855dc8010b899..013359cc8f084 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.types.ts @@ -1,4 +1,4 @@ -import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/internals'; +import { BaseSingleInputFieldProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { DesktopDateRangePickerProps, DesktopDateRangePickerSlots, @@ -46,4 +46,8 @@ export interface DateRangePickerProps = ValidateDateRangeProps & - BaseSingleInputFieldProps; + BaseSingleInputFieldProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + DateRangeValidationError + >; diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx index 80874d788a898..0fcda265e6613 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx @@ -11,6 +11,7 @@ import { useUtils, BaseToolbarProps, ExportedBaseToolbarProps, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { UseRangePositionResponse } from '../internals/hooks/useRangePosition'; @@ -31,7 +32,7 @@ const useUtilityClasses = (ownerState: DateRangePickerToolbarProps) => { export interface DateRangePickerToolbarProps extends ExportedDateRangePickerToolbarProps, - Omit, 'onChange' | 'isLandscape'>, + Omit, 'onChange' | 'isLandscape'>, Pick {} export interface ExportedDateRangePickerToolbarProps extends ExportedBaseToolbarProps { diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx index 4c44f8e7fab27..b098d57cfb0f3 100644 --- a/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateRangePicker/shared.tsx @@ -9,6 +9,7 @@ import { BaseDateValidationProps, BasePickerInputProps, PickerViewRendererLookup, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { DateRangeValidationError } from '../models'; import { @@ -37,7 +38,7 @@ export interface BaseDateRangePickerSlotProps extends DateRangeCalendarSlotProps export interface BaseDateRangePickerProps extends Omit< - BasePickerInputProps, + BasePickerInputProps, 'view' | 'views' | 'openTo' | 'onViewChange' | 'orientation' >, ExportedDateRangeCalendarProps { @@ -57,7 +58,7 @@ export interface BaseDateRangePickerProps * If `undefined`, internally defined view will be used. */ viewRenderers?: Partial< - PickerViewRendererLookup, {}> + PickerViewRendererLookup, {}> >; } diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx index c4d6e1d2789bf..048716130d041 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx @@ -226,17 +226,17 @@ DateTimeRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -250,9 +250,9 @@ DateTimeRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts index b916bfb9b12ab..509f8246c2cef 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.types.ts @@ -1,4 +1,4 @@ -import { BaseSingleInputFieldProps } from '@mui/x-date-pickers/internals'; +import { BaseSingleInputFieldProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { DesktopDateTimeRangePickerProps, DesktopDateTimeRangePickerSlots, @@ -47,4 +47,8 @@ export interface DateTimeRangePickerProps = ValidateDateTimeRangeProps & - BaseSingleInputFieldProps; + BaseSingleInputFieldProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + DateTimeRangeValidationError + >; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx index 832d51e38e2bd..653a818b33b66 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTimeWrapper.tsx @@ -35,7 +35,7 @@ export type DateTimeRangePickerTimeWrapperProps< selectionState: PickerSelectionState, selectedView: TView, ) => void; - viewRenderer?: PickerViewRenderer | null; + viewRenderer?: PickerViewRenderer | null; openTo?: TView; }; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx index bf05e333f0c64..00e362c8e0674 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx @@ -10,6 +10,7 @@ import { useUtils, DateOrTimeViewWithMeridiem, WrapperVariant, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { PickerValidDate } from '@mui/x-date-pickers/models'; @@ -38,7 +39,7 @@ const useUtilityClasses = (ownerState: DateTimeRangePickerToolbarProps) => { type DateTimeRangeViews = Exclude; export interface DateTimeRangePickerToolbarProps - extends BaseToolbarProps, + extends BaseToolbarProps, Pick, ExportedDateTimeRangePickerToolbarProps { ampm?: boolean; diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx index 575c9fd41bea8..d3f2d3127fd93 100644 --- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx +++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/shared.tsx @@ -17,6 +17,7 @@ import { UseViewsOptions, DateTimeValidationProps, DateOrTimeViewWithMeridiem, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { TimeViewRendererProps } from '@mui/x-date-pickers/timeViewRenderers'; import { DigitalClockSlots, DigitalClockSlotProps } from '@mui/x-date-pickers/DigitalClock'; @@ -77,7 +78,7 @@ export type DateTimeRangePickerRenderers< TView extends DateOrTimeViewWithMeridiem, TAdditionalProps extends {} = {}, > = PickerViewRendererLookup< - true, + PickerRangeValue, TView, Omit, 'view' | 'slots' | 'slotProps'> & Omit< @@ -89,13 +90,15 @@ export type DateTimeRangePickerRenderers< export interface BaseDateTimeRangePickerProps extends Omit< - BasePickerInputProps, + BasePickerInputProps, 'orientation' | 'views' | 'openTo' >, ExportedDateRangeCalendarProps, BaseDateValidationProps, DesktopOnlyTimePickerProps, - Partial, 'openTo' | 'views'>>, + Partial< + Pick, 'openTo' | 'views'> + >, DateTimeValidationProps { /** * Overridable component slots. diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx index 6e24f1f599b76..89c2044978b45 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx @@ -1,7 +1,11 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { PickerViewRendererLookup, useUtils } from '@mui/x-date-pickers/internals'; +import { + PickerViewRendererLookup, + useUtils, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; import resolveComponentProps from '@mui/utils/resolveComponentProps'; @@ -42,7 +46,7 @@ const DesktopDateRangePicker = React.forwardRef(function DesktopDateRangePicker< DesktopDateRangePickerProps >(inProps, 'MuiDesktopDateRangePicker'); - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; @@ -230,17 +234,17 @@ DesktopDateRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -254,9 +258,9 @@ DesktopDateRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx index 69964b4838ba0..f9255bdd65af6 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/tests/describes.DesktopDateRangePicker.test.tsx @@ -12,7 +12,7 @@ import { } from 'test/utils/pickers'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerNonNullableRangeValue, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -46,7 +46,7 @@ describe(' - Describes', () => { ], })); - describeValue(DesktopDateRangePicker, () => ({ + describeValue(DesktopDateRangePicker, () => ({ render, componentFamily: 'picker', type: 'date-range', @@ -77,7 +77,7 @@ describe(' - Describes', () => { value, { isOpened, applySameValue, setEndDate = false, selectSection, pressKey }, ) => { - let newValue: DateRange; + let newValue: PickerNonNullableRangeValue; if (applySameValue) { newValue = value; } else if (setEndDate) { @@ -102,7 +102,7 @@ describe(' - Describes', () => { })); // With single input field - describeValue(DesktopDateRangePicker, () => ({ + describeValue(DesktopDateRangePicker, () => ({ render, componentFamily: 'picker', type: 'date-range', @@ -139,7 +139,7 @@ describe(' - Describes', () => { value, { isOpened, applySameValue, setEndDate = false, selectSection, pressKey }, ) => { - let newValue: DateRange; + let newValue: PickerNonNullableRangeValue; if (applySameValue) { newValue = value; } else if (setEndDate) { diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx index d26bc2f32edfb..4c93efaf101e3 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx @@ -9,6 +9,7 @@ import { PickerViewsRendererProps, resolveDateTimeFormat, useUtils, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; @@ -50,7 +51,7 @@ const rendererInterceptor = function rendererInterceptor< inViewRenderers: DateTimeRangePickerRenderers, popperView: DateTimeRangePickerView, rendererProps: PickerViewsRendererProps< - true, + PickerRangeValue, DateTimeRangePickerView, DefaultizedProps< Omit< @@ -102,7 +103,7 @@ const rendererInterceptor = function rendererInterceptor< openTo={isInternalTimeView(openTo) ? openTo : 'hours'} viewRenderer={ inViewRenderers[isTimeViewActive ? popperView : 'hours'] as PickerViewRenderer< - true, + PickerRangeValue, DateTimeRangePickerView, any, {} @@ -391,17 +392,17 @@ DesktopDateTimeRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -415,9 +416,9 @@ DesktopDateTimeRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx index 25c6683aac2f5..dfdd329087ff3 100644 --- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/tests/describes.DesktopDateTimeRangePicker.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { describeConformance, fireEvent, screen } from '@mui/internal-test-utils'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerNonNullableRangeValue, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { createPickerRenderer, adapterToUse, @@ -47,7 +47,7 @@ describe(' - Describes', () => { ], })); - describeValue(DesktopDateTimeRangePicker, () => ({ + describeValue(DesktopDateTimeRangePicker, () => ({ render, componentFamily: 'picker', type: 'date-time-range', @@ -87,7 +87,7 @@ describe(' - Describes', () => { value, { isOpened, applySameValue, setEndDate = false, selectSection, pressKey }, ) => { - let newValue: DateRange; + let newValue: PickerNonNullableRangeValue; if (applySameValue) { newValue = value; } else if (setEndDate) { diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx index 791b84f5be65e..979adfea04843 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx @@ -1,7 +1,11 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { PickerViewRendererLookup, useUtils } from '@mui/x-date-pickers/internals'; +import { + PickerViewRendererLookup, + useUtils, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; import resolveComponentProps from '@mui/utils/resolveComponentProps'; @@ -42,7 +46,7 @@ const MobileDateRangePicker = React.forwardRef(function MobileDateRangePicker< MobileDateRangePickerProps >(inProps, 'MuiMobileDateRangePicker'); - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; @@ -226,17 +230,17 @@ MobileDateRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -250,9 +254,9 @@ MobileDateRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx index f40358155963b..21c28526cdc94 100644 --- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/tests/describes.MobileDateRangePicker.test.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { screen, fireDiscreteEvent, fireEvent } from '@mui/internal-test-utils'; import { MobileDateRangePicker } from '@mui/x-date-pickers-pro/MobileDateRangePicker'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerNonNullableRangeValue, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { adapterToUse, createPickerRenderer, @@ -46,7 +46,7 @@ describe(' - Describes', () => { ], })); - describeValue(MobileDateRangePicker, () => ({ + describeValue(MobileDateRangePicker, () => ({ render, componentFamily: 'picker', type: 'date-range', @@ -74,7 +74,7 @@ describe(' - Describes', () => { expectFieldValueV7(endFieldRoot, expectedEndValueStr); }, setNewValue: (value, { isOpened, applySameValue, setEndDate = false }) => { - let newValue: DateRange; + let newValue: PickerNonNullableRangeValue; if (applySameValue) { newValue = value; } else if (setEndDate) { diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx index 2d43eca365209..05cd5521a2ce9 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx @@ -13,6 +13,7 @@ import { TimeViewWithMeridiem, resolveDateTimeFormat, useUtils, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { extractValidationProps } from '@mui/x-date-pickers/validation'; import { PickerOwnerState } from '@mui/x-date-pickers/models'; @@ -49,7 +50,7 @@ const rendererInterceptor = function rendererInterceptor< inViewRenderers: DateTimeRangePickerRenderers, popperView: DateTimeRangePickerView, rendererProps: PickerViewsRendererProps< - true, + PickerRangeValue, DateTimeRangePickerView, DefaultizedProps< UseMobileRangePickerProps< @@ -101,7 +102,9 @@ const rendererInterceptor = function rendererInterceptor< return ( } + viewRenderer={ + viewRenderer as PickerViewRenderer + } view={view && isInternalTimeView(view) ? view : 'hours'} views={finalProps.views as TimeViewWithMeridiem[]} openTo={isInternalTimeView(openTo) ? openTo : 'hours'} @@ -109,7 +112,7 @@ const rendererInterceptor = function rendererInterceptor< ); } // avoiding problem of `props: never` - const typedViewRenderer = viewRenderer as PickerViewRenderer; + const typedViewRenderer = viewRenderer as PickerViewRenderer; return typedViewRenderer({ ...finalProps, @@ -378,17 +381,17 @@ MobileDateTimeRangePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -402,9 +405,9 @@ MobileDateTimeRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx index 2650507d38b53..90a5dc4057ec1 100644 --- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx +++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/tests/describes.MobileDateTimeRangePicker.test.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { describeConformance, fireEvent, screen } from '@mui/internal-test-utils'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerNonNullableRangeValue, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { createPickerRenderer, adapterToUse, @@ -11,7 +11,7 @@ import { getFieldSectionsContainer, openPicker, } from 'test/utils/pickers'; -import { MobileDateTimeRangePicker } from '../MobileDateTimeRangePicker'; +import { MobileDateTimeRangePicker } from '@mui/x-date-pickers-pro/MobileDateTimeRangePicker'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -48,7 +48,7 @@ describe(' - Describes', () => { ], })); - describeValue(MobileDateTimeRangePicker, () => ({ + describeValue(MobileDateTimeRangePicker, () => ({ render, componentFamily: 'picker', type: 'date-time-range', @@ -92,7 +92,7 @@ describe(' - Describes', () => { initialFocus: setEndDate ? 'end' : 'start', }); } - let newValue: DateRange; + let newValue: PickerNonNullableRangeValue; if (applySameValue) { newValue = value; } else if (setEndDate) { diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx index 1cf2f51022638..c3c9fb73c19d5 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx @@ -255,9 +255,9 @@ MultiInputDateRangeField.propTypes = { minDate: PropTypes.object, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -266,9 +266,9 @@ MultiInputDateRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 f4e18707f6536..3531d3a14dd9d 100644 --- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx @@ -286,9 +286,9 @@ MultiInputDateTimeRangeField.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -297,9 +297,9 @@ MultiInputDateTimeRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx index 0848f38272ac4..c533888fd193c 100644 --- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx @@ -271,9 +271,9 @@ MultiInputTimeRangeField.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -282,9 +282,9 @@ MultiInputTimeRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx index 009953d70c845..02f127c0c715d 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx @@ -214,9 +214,9 @@ SingleInputDateRangeField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -229,9 +229,9 @@ SingleInputDateRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, onFocus: PropTypes.func, diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts index ac6817f6a3d95..90d138c59c32e 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.types.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/utils'; import TextField from '@mui/material/TextField'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals'; import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models'; import { ExportedUseClearableFieldProps, @@ -15,7 +15,11 @@ export interface UseSingleInputDateRangeFieldProps< > extends UseDateRangeFieldProps, ExportedUseClearableFieldProps, Pick< - UseFieldInternalProps, + UseFieldInternalProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + DateRangeValidationError + >, 'unstableFieldRef' > {} diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts index 75ae6ce7b018b..e1b71090039e7 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts @@ -1,6 +1,6 @@ 'use client'; import * as React from 'react'; -import { useField, useDefaultizedDateField } from '@mui/x-date-pickers/internals'; +import { useField, useDefaultizedDateField, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; import { UseSingleInputDateRangeFieldProps } from './SingleInputDateRangeField.types'; import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers'; @@ -25,7 +25,7 @@ export const useSingleInputDateRangeField = < ); return useField< - true, + PickerRangeValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx index fc8a131f2997e..1c3a0b1469dd2 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx @@ -247,9 +247,9 @@ SingleInputDateTimeRangeField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -262,9 +262,9 @@ SingleInputDateTimeRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, onFocus: PropTypes.func, diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts index da7292cfe1201..53079837d53c5 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.types.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/utils'; import TextField from '@mui/material/TextField'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals'; import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models'; import { ExportedUseClearableFieldProps, @@ -16,7 +16,11 @@ export interface UseSingleInputDateTimeRangeFieldProps< > extends UseDateTimeRangeFieldProps, ExportedUseClearableFieldProps, Pick< - UseFieldInternalProps, + UseFieldInternalProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + DateTimeRangeValidationError + >, 'unstableFieldRef' > {} diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts index 2e2dc22065a56..1fbed22a25d09 100644 --- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts @@ -1,6 +1,10 @@ 'use client'; import * as React from 'react'; -import { useField, useDefaultizedDateTimeField } from '@mui/x-date-pickers/internals'; +import { + useField, + useDefaultizedDateTimeField, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; import { UseSingleInputDateTimeRangeFieldProps } from './SingleInputDateTimeRangeField.types'; import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers'; @@ -25,7 +29,7 @@ export const useSingleInputDateTimeRangeField = < ); return useField< - true, + PickerRangeValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx index 6638f805cab9a..ff5b9d8524cd9 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx @@ -229,9 +229,9 @@ SingleInputTimeRangeField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -244,9 +244,9 @@ SingleInputTimeRangeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, onFocus: PropTypes.func, diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts index 2a19d339bd14d..a1b94ce63cd70 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.types.ts @@ -1,7 +1,7 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/utils'; import TextField from '@mui/material/TextField'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals'; import { BuiltInFieldTextFieldProps } from '@mui/x-date-pickers/models'; import { ExportedUseClearableFieldProps, @@ -16,7 +16,11 @@ export interface UseSingleInputTimeRangeFieldProps< > extends UseTimeRangeFieldProps, ExportedUseClearableFieldProps, Pick< - UseFieldInternalProps, + UseFieldInternalProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + TimeRangeValidationError + >, 'unstableFieldRef' > {} diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts index 2c1933eae3e61..a55e35d42c97f 100644 --- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts +++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts @@ -1,6 +1,6 @@ 'use client'; import * as React from 'react'; -import { useField, useDefaultizedTimeField } from '@mui/x-date-pickers/internals'; +import { useField, useDefaultizedTimeField, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; import { UseSingleInputTimeRangeFieldProps } from './SingleInputTimeRangeField.types'; import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers'; @@ -25,7 +25,7 @@ export const useSingleInputTimeRangeField = < ); return useField< - true, + PickerRangeValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx index 63018d7341092..ee9f8f61066f7 100644 --- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; import PropTypes from 'prop-types'; -import { PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, PickerViewRendererLookup } from '@mui/x-date-pickers/internals'; import { useStaticRangePicker } from '../internals/hooks/useStaticRangePicker'; import { StaticDateRangePickerProps } from './StaticDateRangePicker.types'; import { useDateRangePickerDefaultizedProps } from '../DateRangePicker/shared'; @@ -34,7 +34,7 @@ const StaticDateRangePicker = React.forwardRef(function StaticDateRangePicker( const displayStaticWrapperAs = defaultizedProps.displayStaticWrapperAs ?? 'mobile'; - const viewRenderers: PickerViewRendererLookup = { + const viewRenderers: PickerViewRendererLookup = { day: renderDateRangeViewCalendar, ...defaultizedProps.viewRenderers, }; @@ -176,17 +176,17 @@ StaticDateRangePicker.propTypes = { minDate: PropTypes.object, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -201,9 +201,9 @@ StaticDateRangePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts index 4b016b05104d0..bf22eeb38d5d5 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/models/useRangePicker.ts @@ -8,6 +8,7 @@ import { UsePickerViewsNonStaticProps, DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { ExportedPickersLayoutSlots, @@ -21,13 +22,13 @@ import { } from '../useEnrichedRangePickerFieldProps'; export interface UseRangePickerSlots - extends ExportedPickersLayoutSlots, + extends ExportedPickersLayoutSlots, RangePickerFieldSlots {} export interface UseRangePickerSlotProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, -> extends ExportedPickersLayoutSlotProps, +> extends ExportedPickersLayoutSlotProps, RangePickerFieldSlotProps { tabs?: ExportedBaseTabsProps; toolbar?: ExportedBaseToolbarProps; @@ -46,7 +47,7 @@ export interface UseRangePickerProps< TExternalProps extends UsePickerViewsProps, TAdditionalViewProps extends {}, > extends RangeOnlyPickerProps, - BasePickerProps {} + BasePickerProps {} export interface RangePickerAdditionalViewProps extends Pick {} @@ -56,7 +57,7 @@ export interface UseRangePickerParams< TExternalProps extends UseRangePickerProps, TAdditionalViewProps extends {}, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' | 'rendererInterceptor' > { props: TExternalProps; 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 fac517d4fa24e..9a7c9443cff3d 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 @@ -11,6 +11,8 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, PickerProvider, + PickerValue, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { FieldRef, InferError } from '@mui/x-date-pickers/models'; import { @@ -67,9 +69,9 @@ export const useDesktopRangePicker = < const fieldContainerRef = React.useRef(null); const anchorRef = React.useRef(null); const popperRef = React.useRef(null); - const startFieldRef = React.useRef>(null); - const endFieldRef = React.useRef>(null); - const singleInputFieldRef = React.useRef>(null); + const startFieldRef = React.useRef>(null); + const endFieldRef = React.useRef>(null); + const singleInputFieldRef = React.useRef>(null); const initialView = React.useRef(props.openTo ?? null); const fieldType = (slots.field as any).fieldType ?? 'multi-input'; @@ -78,7 +80,7 @@ export const useDesktopRangePicker = < fieldType === 'single-input' ? singleInputFieldRef : undefined, ); - let fieldRef: React.Ref>; + let fieldRef: React.RefObject | FieldRef>; if (fieldType === 'single-input') { fieldRef = singleInputFieldRef; } else if (rangePosition === 'start') { @@ -96,7 +98,7 @@ export const useDesktopRangePicker = < shouldRestoreFocus, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, wrapperVariant: 'desktop', @@ -189,7 +191,7 @@ export const useDesktopRangePicker = < onViewChange: layoutProps.onViewChange, }); - const slotPropsForLayout: PickersLayoutSlotProps = { + const slotPropsForLayout: PickersLayoutSlotProps = { ...slotProps, tabs: { ...slotProps?.tabs, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts index 2b920f023710b..8a761aa254fa2 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -19,6 +19,8 @@ import { WrapperVariant, DateOrTimeViewWithMeridiem, BaseSingleInputFieldProps, + PickerRangeValue, + PickerValue, } from '@mui/x-date-pickers/internals'; import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; import { @@ -74,7 +76,7 @@ export type RangePickerPropsForFieldSlot< TError, > = | (TIsSingleInput extends true - ? BaseSingleInputFieldProps + ? BaseSingleInputFieldProps : never) | (TIsSingleInput extends false ? BaseMultiInputFieldProps @@ -85,7 +87,7 @@ export interface UseEnrichedRangePickerFieldPropsParams< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, -> extends Pick, 'open' | 'actions'>, +> extends Pick, 'open' | 'actions'>, UseRangePositionResponse { wrapperVariant: WrapperVariant; fieldType: FieldType; @@ -106,9 +108,9 @@ export interface UseEnrichedRangePickerFieldPropsParams< currentView?: TView | null; initialView?: TView; onViewChange?: (view: TView) => void; - startFieldRef: React.RefObject>; - endFieldRef: React.RefObject>; - singleInputFieldRef: React.RefObject>; + startFieldRef: React.RefObject>; + endFieldRef: React.RefObject>; + singleInputFieldRef: React.RefObject>; } const useMultiInputFieldSlotProps = < @@ -311,7 +313,11 @@ const useSingleInputFieldSlotProps = < TEnableAccessibleFieldDOMStructure, TError >) => { - type ReturnType = BaseSingleInputFieldProps; + type ReturnType = BaseSingleInputFieldProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + TError + >; const handleFieldRef = useForkRef(fieldProps.unstableFieldRef, singleInputFieldRef); 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 bd8938b29937a..dbe5d3abb8372 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 @@ -9,6 +9,8 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, PickerProvider, + PickerRangeValue, + PickerValue, } from '@mui/x-date-pickers/internals'; import { usePickerTranslations } from '@mui/x-date-pickers/hooks'; import { FieldRef, InferError } from '@mui/x-date-pickers/models'; @@ -62,9 +64,9 @@ export const useMobileRangePicker = < localeText, } = props; - const startFieldRef = React.useRef>(null); - const endFieldRef = React.useRef>(null); - const singleInputFieldRef = React.useRef>(null); + const startFieldRef = React.useRef>(null); + const endFieldRef = React.useRef>(null); + const singleInputFieldRef = React.useRef>(null); const fieldType = (slots.field as any).fieldType ?? 'multi-input'; const { rangePosition, onRangePositionChange } = useRangePosition( @@ -74,7 +76,7 @@ export const useMobileRangePicker = < const labelId = useId(); const contextTranslations = usePickerTranslations(); - let fieldRef: React.Ref>; + let fieldRef: React.Ref | FieldRef>; if (fieldType === 'single-input') { fieldRef = singleInputFieldRef; } else if (rangePosition === 'start') { @@ -91,7 +93,7 @@ export const useMobileRangePicker = < renderCurrentView, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, wrapperVariant: 'mobile', @@ -160,7 +162,7 @@ export const useMobileRangePicker = < singleInputFieldRef, }); - const slotPropsForLayout: PickersLayoutSlotProps = { + const slotPropsForLayout: PickersLayoutSlotProps = { ...innerSlotProps, tabs: { ...innerSlotProps?.tabs, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts index 65c7b308ac578..b5fb7e3f74f05 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputFieldSelectedSections.ts @@ -1,22 +1,26 @@ import * as React from 'react'; import useForkRef from '@mui/utils/useForkRef'; import useEventCallback from '@mui/utils/useEventCallback'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { + PickerRangeValue, + PickerValue, + UseFieldInternalProps, +} from '@mui/x-date-pickers/internals'; import { FieldRef, FieldSelectedSections } from '@mui/x-date-pickers/models'; interface UseMultiInputFieldSelectedSectionsParams extends Pick< - UseFieldInternalProps, + UseFieldInternalProps, 'selectedSections' | 'onSelectedSectionsChange' > { - unstableStartFieldRef?: React.Ref>; - unstableEndFieldRef?: React.Ref>; + unstableStartFieldRef?: React.Ref>; + unstableEndFieldRef?: React.Ref>; } export const useMultiInputFieldSelectedSections = ( params: UseMultiInputFieldSelectedSectionsParams, ) => { - const unstableEndFieldRef = React.useRef>(null); + const unstableEndFieldRef = React.useRef>(null); const handleUnstableEndFieldRef = useForkRef(params.unstableEndFieldRef, unstableEndFieldRef); const [startSelectedSection, setStartSelectedSection] = React.useState( 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 1f48ae602878a..7b15ee812462e 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,6 +4,7 @@ import { FieldChangeHandler, FieldChangeHandlerContext, PickerRangeValue, + PickerValue, UseFieldResponse, useControlledValueWithTimezone, useDefaultizedDateField, @@ -73,7 +74,9 @@ export const useMultiInputDateRangeField = < }); // TODO: Maybe export utility from `useField` instead of copy/pasting the logic - const buildChangeHandler = (index: 0 | 1): FieldChangeHandler => { + const buildChangeHandler = ( + index: 0 | 1, + ): FieldChangeHandler => { return (newDate, rawContext) => { const newDateRange: PickerRangeValue = index === 0 ? [newDate, value[1]] : [value[0], newDate]; 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 2eb4995fb5110..699445f0a0168 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,6 +4,7 @@ import { FieldChangeHandler, FieldChangeHandlerContext, PickerRangeValue, + PickerValue, UseFieldResponse, useControlledValueWithTimezone, useDefaultizedDateTimeField, @@ -73,7 +74,9 @@ export const useMultiInputDateTimeRangeField = < }); // TODO: Maybe export utility from `useField` instead of copy/pasting the logic - const buildChangeHandler = (index: 0 | 1): FieldChangeHandler => { + const buildChangeHandler = ( + index: 0 | 1, + ): FieldChangeHandler => { return (newDate, rawContext) => { const newDateRange: PickerRangeValue = index === 0 ? [newDate, value[1]] : [value[0], newDate]; 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 13459313a1c3a..3499db3e1c1a9 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,6 +4,7 @@ import { FieldChangeHandler, FieldChangeHandlerContext, PickerRangeValue, + PickerValue, UseFieldResponse, useControlledValueWithTimezone, useDefaultizedTimeField, @@ -73,7 +74,9 @@ export const useMultiInputTimeRangeField = < }); // TODO: Maybe export utility from `useField` instead of copy/pasting the logic - const buildChangeHandler = (index: 0 | 1): FieldChangeHandler => { + const buildChangeHandler = ( + index: 0 | 1, + ): FieldChangeHandler => { return (newDate, rawContext) => { const newDateRange: PickerRangeValue = index === 0 ? [newDate, value[1]] : [value[0], newDate]; diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts b/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts index 898bf1253a072..4b71d9e2ecb74 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useRangePosition.ts @@ -2,6 +2,7 @@ import * as React from 'react'; import useControlled from '@mui/utils/useControlled'; import useEventCallback from '@mui/utils/useEventCallback'; import { FieldRef } from '@mui/x-date-pickers/models'; +import { PickerRangeValue } from '@mui/x-date-pickers/internals'; import { RangePosition } from '../../models'; export interface UseRangePositionProps { @@ -30,7 +31,7 @@ export interface UseRangePositionResponse { export const useRangePosition = ( props: UseRangePositionProps, - singleInputFieldRef?: React.RefObject>, + singleInputFieldRef?: React.RefObject>, ): UseRangePositionResponse => { const [rangePosition, setRangePosition] = useControlled({ name: 'useRangePosition', diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx index 85c0e833d4a13..8befe74f5cf46 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.tsx @@ -8,6 +8,7 @@ import { ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, PickerProvider, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { UseStaticRangePickerParams, @@ -38,7 +39,7 @@ export const useStaticRangePicker = < const { rangePosition, onRangePositionChange } = useRangePosition(props); const { layoutProps, providerProps, renderCurrentView } = usePicker< - true, + PickerRangeValue, TView, TExternalProps, {} @@ -56,7 +57,7 @@ export const useStaticRangePicker = < }); const Layout = slots?.layout ?? PickerStaticLayout; - const slotPropsForLayout: PickersLayoutSlotProps = { + const slotPropsForLayout: PickersLayoutSlotProps = { ...slotProps, toolbar: { ...slotProps?.toolbar, diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts index 75fe7c3b90752..b4c62b6437d0a 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useStaticRangePicker/useStaticRangePicker.types.ts @@ -5,6 +5,7 @@ import { ExportedBaseToolbarProps, StaticOnlyPickerProps, DateOrTimeViewWithMeridiem, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { ExportedPickersLayoutSlots, @@ -13,10 +14,10 @@ import { import { UseRangePositionProps } from '../useRangePosition'; export interface UseStaticRangePickerSlots - extends ExportedPickersLayoutSlots {} + extends ExportedPickersLayoutSlots {} export interface UseStaticRangePickerSlotProps - extends ExportedPickersLayoutSlotProps { + extends ExportedPickersLayoutSlotProps { toolbar?: ExportedBaseToolbarProps; } @@ -26,7 +27,7 @@ export interface UseStaticRangePickerProps< TView extends DateOrTimeViewWithMeridiem, TError, TExternalProps extends UseStaticRangePickerProps, -> extends BasePickerProps, +> extends BasePickerProps, StaticRangeOnlyPickerProps { /** * Overridable components. @@ -44,7 +45,7 @@ export interface UseStaticRangePickerParams< TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticRangePickerProps, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; diff --git a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts index 26f59a768b5da..dddac7c0a86bc 100644 --- a/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/dateTimeRange.ts @@ -3,6 +3,7 @@ import { UseFieldInternalProps, DateOrTimeViewWithMeridiem, AmPmProps, + PickerRangeValue, } from '@mui/x-date-pickers/internals'; import { DateTimeRangeValidationError, RangeFieldSeparatorProps } from '../../models'; import { ExportedValidateDateTimeRangeProps } from '../../validation/validateDateTimeRange'; @@ -11,7 +12,7 @@ export interface UseDateTimeRangeFieldProps, diff --git a/packages/x-date-pickers-pro/src/internals/models/fields.ts b/packages/x-date-pickers-pro/src/internals/models/fields.ts index 5957fc1a0cda9..c0a227ac3f982 100644 --- a/packages/x-date-pickers-pro/src/internals/models/fields.ts +++ b/packages/x-date-pickers-pro/src/internals/models/fields.ts @@ -1,7 +1,7 @@ import { SxProps } from '@mui/material/styles'; import { SlotComponentProps } from '@mui/utils'; import { MakeRequired } from '@mui/x-internals/types'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals'; import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; import type { MultiInputFieldRefs, @@ -19,7 +19,7 @@ export interface BaseMultiInputFieldProps< TError, > extends MakeRequired< Pick< - UseFieldInternalProps, + UseFieldInternalProps, | 'readOnly' | 'disabled' | 'format' diff --git a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts index 6bd2c88f67691..171ad2c8c7cdb 100644 --- a/packages/x-date-pickers-pro/src/internals/models/timeRange.ts +++ b/packages/x-date-pickers-pro/src/internals/models/timeRange.ts @@ -1,12 +1,16 @@ import { MakeOptional } from '@mui/x-internals/types'; -import { UseFieldInternalProps, AmPmProps } from '@mui/x-date-pickers/internals'; +import { UseFieldInternalProps, AmPmProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { TimeRangeValidationError, RangeFieldSeparatorProps } from '../../models'; import type { ExportedValidateTimeRangeProps } from '../../validation/validateTimeRange'; export interface UseTimeRangeFieldProps extends MakeOptional< Omit< - UseFieldInternalProps, + UseFieldInternalProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + TimeRangeValidationError + >, 'unstableFieldRef' >, 'format' diff --git a/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts b/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts index 8eebc73534048..59009cfebe630 100644 --- a/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts +++ b/packages/x-date-pickers-pro/src/internals/utils/valueManagers.ts @@ -25,7 +25,7 @@ type RangePickerValueManager< | DateRangeValidationError | TimeRangeValidationError | DateTimeRangeValidationError = any, -> = PickerValueManager; +> = PickerValueManager; export const rangeValueManager: RangePickerValueManager = { emptyValue: [null, null], @@ -77,7 +77,7 @@ export const getRangeFieldValueManager = ({ dateSeparator = '–', }: { dateSeparator: string | undefined; -}): FieldValueManager => ({ +}): FieldValueManager => ({ updateReferenceValue: (utils, value, prevReferenceValue) => { const shouldKeepStartDate = value[0] != null && utils.isValid(value[0]); const shouldKeepEndDate = value[1] != null && utils.isValid(value[1]); diff --git a/packages/x-date-pickers-pro/src/models/dateRange.ts b/packages/x-date-pickers-pro/src/models/dateRange.ts index 0d9c9e8e349f4..0e29e30990cc1 100644 --- a/packages/x-date-pickers-pro/src/models/dateRange.ts +++ b/packages/x-date-pickers-pro/src/models/dateRange.ts @@ -1,5 +1,5 @@ import { MakeOptional } from '@mui/x-internals/types'; -import { UseFieldInternalProps } from '@mui/x-date-pickers/internals'; +import { PickerRangeValue, UseFieldInternalProps } from '@mui/x-date-pickers/internals'; import { RangeFieldSeparatorProps } from './fields'; import { DateRangeValidationError } from './validation'; import type { ExportedValidateDateRangeProps } from '../validation/validateDateRange'; @@ -7,7 +7,11 @@ import type { ExportedValidateDateRangeProps } from '../validation/validateDateR export interface UseDateRangeFieldProps extends MakeOptional< Omit< - UseFieldInternalProps, + UseFieldInternalProps< + PickerRangeValue, + TEnableAccessibleFieldDOMStructure, + DateRangeValidationError + >, 'unstableFieldRef' >, 'format' diff --git a/packages/x-date-pickers-pro/src/models/fields.ts b/packages/x-date-pickers-pro/src/models/fields.ts index ea23ffc5dee44..648dc4c4f277a 100644 --- a/packages/x-date-pickers-pro/src/models/fields.ts +++ b/packages/x-date-pickers-pro/src/models/fields.ts @@ -1,5 +1,10 @@ import * as React from 'react'; -import { UseFieldResponse, FormProps } from '@mui/x-date-pickers/internals'; +import { + UseFieldResponse, + FormProps, + PickerValue, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { FieldRef, PickerFieldSlotProps } from '@mui/x-date-pickers/models'; import { UseClearableFieldResponse } from '@mui/x-date-pickers/hooks'; @@ -32,8 +37,8 @@ export interface MultiInputFieldSlotRootProps { } export interface MultiInputFieldRefs { - unstableStartFieldRef?: React.Ref>; - unstableEndFieldRef?: React.Ref>; + unstableStartFieldRef?: React.Ref>; + unstableEndFieldRef?: React.Ref>; } export interface RangeFieldSeparatorProps { @@ -48,7 +53,8 @@ export interface RangeFieldSeparatorProps { * Props the `slotProps.field` of a range picker component can receive. */ export type PickerRangeFieldSlotProps = - PickerFieldSlotProps & RangeFieldSeparatorProps; + PickerFieldSlotProps & + RangeFieldSeparatorProps; /** * Props the text field receives when used with a multi input picker. diff --git a/packages/x-date-pickers-pro/src/validation/validateDateRange.ts b/packages/x-date-pickers-pro/src/validation/validateDateRange.ts index 02d776903e093..44effa217b603 100644 --- a/packages/x-date-pickers-pro/src/validation/validateDateRange.ts +++ b/packages/x-date-pickers-pro/src/validation/validateDateRange.ts @@ -1,5 +1,5 @@ import { validateDate, Validator } from '@mui/x-date-pickers/validation'; -import { BaseDateValidationProps } from '@mui/x-date-pickers/internals'; +import { BaseDateValidationProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { isRangeValid } from '../internals/utils/date-utils'; import { DayRangeValidationProps } from '../internals/models/dateRange'; import { DateRangeValidationError } from '../models'; @@ -17,7 +17,7 @@ export interface ValidateDateRangeProps Required {} export const validateDateRange: Validator< - true, + PickerRangeValue, DateRangeValidationError, ValidateDateRangeProps > = ({ adapter, value, timezone, props }) => { diff --git a/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts b/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts index 25543de73599d..743360be7d7d7 100644 --- a/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts +++ b/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts @@ -1,4 +1,4 @@ -import { DateTimeValidationProps } from '@mui/x-date-pickers/internals'; +import { DateTimeValidationProps, PickerRangeValue } from '@mui/x-date-pickers/internals'; import { validateDateTime, Validator } from '@mui/x-date-pickers/validation'; import { isRangeValid } from '../internals/utils/date-utils'; import { DateTimeRangeValidationError } from '../models'; @@ -19,7 +19,7 @@ export interface ValidateDateTimeRangeProps ValidateTimeRangeProps {} export const validateDateTimeRange: Validator< - true, + PickerRangeValue, DateTimeRangeValidationError, ValidateDateTimeRangeProps > = ({ adapter, value, timezone, props }) => { diff --git a/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts b/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts index 5ced51e9309a9..2f5cd591cd86a 100644 --- a/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts +++ b/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts @@ -1,5 +1,9 @@ import { validateTime, Validator } from '@mui/x-date-pickers/validation'; -import { TimeValidationProps, BaseTimeValidationProps } from '@mui/x-date-pickers/internals'; +import { + TimeValidationProps, + BaseTimeValidationProps, + PickerRangeValue, +} from '@mui/x-date-pickers/internals'; import { isRangeValid } from '../internals/utils/date-utils'; import { TimeRangeValidationError } from '../models'; import { rangeValueManager } from '../internals/utils/valueManagers'; @@ -16,7 +20,7 @@ export interface ValidateTimeRangeProps TimeValidationProps {} export const validateTimeRange: Validator< - true, + PickerRangeValue, TimeRangeValidationError, ValidateTimeRangeProps > = ({ adapter, value, timezone, props }) => { diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx index 02cef653920eb..cf3693d62dd54 100644 --- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx +++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.tsx @@ -32,6 +32,7 @@ import { singleItemValueManager } from '../internals/utils/valueManagers'; import { VIEW_HEIGHT } from '../internals/constants/dimensions'; import { PickerOwnerState, PickerValidDate, DateView } from '../models'; import { usePickerPrivateContext } from '../internals/hooks/usePickerPrivateContext'; +import { PickerValue } from '../internals/models'; const useUtilityClasses = (classes: Partial | undefined) => { const slots = { @@ -161,7 +162,7 @@ export const DateCalendar = React.forwardRef(function DateCalendar( }); const { view, setView, focusedView, setFocusedView, goToNextView, setValueAndGoToNextView } = - useViews({ + useViews({ view: inView, views, openTo, @@ -492,9 +493,9 @@ DateCalendar.propTypes = { monthsPerRow: PropTypes.oneOf([3, 4]), /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ diff --git a/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts b/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts index fabacf8c6a777..022149cfdc804 100644 --- a/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts +++ b/packages/x-date-pickers/src/DateCalendar/DateCalendar.types.ts @@ -26,6 +26,7 @@ import { } from '../MonthCalendar/MonthCalendar.types'; import { ExportedValidateDateProps } from '../validation/validateDate'; import { FormProps } from '../internals/models/formProps'; +import { PickerValue } from '../internals/models'; export interface DateCalendarSlots extends PickersCalendarHeaderSlots, @@ -80,7 +81,7 @@ export interface ExportedDateCalendarProps export interface DateCalendarProps extends ExportedDateCalendarProps, - ExportedUseViewsOptions { + ExportedUseViewsOptions { /** * The selected value. * Used when the component is controlled. diff --git a/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx b/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx index 20719cfa50294..0993722c40b47 100644 --- a/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx +++ b/packages/x-date-pickers/src/DateCalendar/tests/describes.DateCalendar.test.tsx @@ -3,6 +3,7 @@ import { expect } from 'chai'; import { fireEvent, screen } from '@mui/internal-test-utils'; import { DateCalendar, dateCalendarClasses as classes } from '@mui/x-date-pickers/DateCalendar'; import { pickersDayClasses } from '@mui/x-date-pickers/PickersDay'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { adapterToUse, createPickerRenderer, @@ -30,7 +31,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(DateCalendar, () => ({ + describeValue(DateCalendar, () => ({ render, componentFamily: 'calendar', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-02')], diff --git a/packages/x-date-pickers/src/DateField/DateField.tsx b/packages/x-date-pickers/src/DateField/DateField.tsx index f46c93cce9010..0a79fa946a2f9 100644 --- a/packages/x-date-pickers/src/DateField/DateField.tsx +++ b/packages/x-date-pickers/src/DateField/DateField.tsx @@ -201,9 +201,9 @@ DateField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -216,9 +216,9 @@ DateField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 21dd20cd0e5f7..57e48ff53e200 100644 --- a/packages/x-date-pickers/src/DateField/DateField.types.ts +++ b/packages/x-date-pickers/src/DateField/DateField.types.ts @@ -10,10 +10,11 @@ import { import { DateValidationError, BuiltInFieldTextFieldProps } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; import { ExportedValidateDateProps } from '../validation/validateDate'; +import { PickerValue } from '../internals/models'; export interface UseDateFieldProps extends MakeOptional< - UseFieldInternalProps, + UseFieldInternalProps, 'format' >, ExportedValidateDateProps, diff --git a/packages/x-date-pickers/src/DateField/tests/describes.DateField.test.tsx b/packages/x-date-pickers/src/DateField/tests/describes.DateField.test.tsx index 6dd33c79d5d5c..c1441c9e3f0ea 100644 --- a/packages/x-date-pickers/src/DateField/tests/describes.DateField.test.tsx +++ b/packages/x-date-pickers/src/DateField/tests/describes.DateField.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; import { DateField } from '@mui/x-date-pickers/DateField'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { createPickerRenderer, expectFieldValueV7, @@ -30,7 +31,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants', 'themeStyleOverrides'], })); - describeValue(DateField, () => ({ + describeValue(DateField, () => ({ render, componentFamily: 'field', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-02')], diff --git a/packages/x-date-pickers/src/DateField/useDateField.ts b/packages/x-date-pickers/src/DateField/useDateField.ts index 358c87124e489..42d7b01fe3a82 100644 --- a/packages/x-date-pickers/src/DateField/useDateField.ts +++ b/packages/x-date-pickers/src/DateField/useDateField.ts @@ -8,6 +8,7 @@ import { UseDateFieldProps } from './DateField.types'; import { validateDate } from '../validation'; import { useSplitFieldProps } from '../hooks'; import { useDefaultizedDateField } from '../internals/hooks/defaultizedFieldProps'; +import { PickerValue } from '../internals/models'; export const useDateField = < TEnableAccessibleFieldDOMStructure extends boolean, @@ -23,7 +24,7 @@ export const useDateField = < const { forwardedProps, internalProps } = useSplitFieldProps(props, 'date'); return useField< - false, + PickerValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx index 068470508c2fa..6efb2dc1d7e1e 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx @@ -166,17 +166,17 @@ DatePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -190,9 +190,9 @@ DatePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts index c652e237b461e..bbccb00651e43 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts @@ -3,7 +3,7 @@ import { DesktopDatePickerSlots, DesktopDatePickerSlotProps, } from '../DesktopDatePicker'; -import { BaseSingleInputFieldProps } from '../internals/models'; +import { BaseSingleInputFieldProps, PickerValue } from '../internals/models'; import { MobileDatePickerProps, MobileDatePickerSlots, @@ -49,4 +49,4 @@ export interface DatePickerProps = ValidateDateProps & - BaseSingleInputFieldProps; + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx index 4b9d5ff0d1381..ea403cfb5fca7 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx @@ -15,9 +15,10 @@ import { getDatePickerToolbarUtilityClass, } from './datePickerToolbarClasses'; import { resolveDateFormat } from '../internals/utils/date-utils'; +import { PickerValue } from '../internals/models'; export interface DatePickerToolbarProps - extends BaseToolbarProps, + extends BaseToolbarProps, ExportedDatePickerToolbarProps {} export interface ExportedDatePickerToolbarProps extends ExportedBaseToolbarProps { diff --git a/packages/x-date-pickers/src/DatePicker/shared.tsx b/packages/x-date-pickers/src/DatePicker/shared.tsx index ce01d42a097d8..769d39e4e03c6 100644 --- a/packages/x-date-pickers/src/DatePicker/shared.tsx +++ b/packages/x-date-pickers/src/DatePicker/shared.tsx @@ -20,6 +20,7 @@ import { } from './DatePickerToolbar'; import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePickerViews'; import { DateViewRendererProps } from '../dateViewRenderers'; +import { PickerValue } from '../internals/models'; export interface BaseDatePickerSlots extends DateCalendarSlots { /** @@ -36,10 +37,10 @@ export interface BaseDatePickerSlotProps extends DateCalendarSlotProps { export type DatePickerViewRenderers< TView extends DateView, TAdditionalProps extends {} = {}, -> = PickerViewRendererLookup, TAdditionalProps>; +> = PickerViewRendererLookup, TAdditionalProps>; export interface BaseDatePickerProps - extends BasePickerInputProps, + extends BasePickerInputProps, ExportedDateCalendarProps { /** * Overridable component slots. diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx index 62bb0b930b59a..20002236886fe 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx @@ -238,9 +238,9 @@ DateTimeField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -253,9 +253,9 @@ DateTimeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 8a5ecfac9f6f0..876545ded3c44 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts @@ -11,10 +11,15 @@ import { } from '../hooks/useClearableField'; import { ExportedValidateDateTimeProps } from '../validation/validateDateTime'; import { AmPmProps } from '../internals/models/props/time'; +import { PickerValue } from '../internals/models'; export interface UseDateTimeFieldProps extends MakeOptional< - UseFieldInternalProps, + UseFieldInternalProps< + PickerValue, + TEnableAccessibleFieldDOMStructure, + DateTimeValidationError + >, 'format' >, ExportedValidateDateTimeProps, diff --git a/packages/x-date-pickers/src/DateTimeField/tests/describes.DateTimeField.test.tsx b/packages/x-date-pickers/src/DateTimeField/tests/describes.DateTimeField.test.tsx index 7ee9a0ef256d5..a4de539e0e8e1 100644 --- a/packages/x-date-pickers/src/DateTimeField/tests/describes.DateTimeField.test.tsx +++ b/packages/x-date-pickers/src/DateTimeField/tests/describes.DateTimeField.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { adapterToUse, createPickerRenderer, @@ -30,7 +31,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants', 'themeStyleOverrides'], })); - describeValue(DateTimeField, () => ({ + describeValue(DateTimeField, () => ({ render, componentFamily: 'field', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-02')], diff --git a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts index d95b01f4b62d0..bd3b0b585352b 100644 --- a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts +++ b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts @@ -8,6 +8,7 @@ import { UseDateTimeFieldProps } from './DateTimeField.types'; import { validateDateTime } from '../validation'; import { useSplitFieldProps } from '../hooks'; import { useDefaultizedDateTimeField } from '../internals/hooks/defaultizedFieldProps'; +import { PickerValue } from '../internals/models'; export const useDateTimeField = < TEnableAccessibleFieldDOMStructure extends boolean, @@ -23,7 +24,7 @@ export const useDateTimeField = < const { forwardedProps, internalProps } = useSplitFieldProps(props, 'date-time'); return useField< - false, + PickerValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx index 4bf130b7c2ae1..24682f5c735c1 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx @@ -208,17 +208,17 @@ DateTimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -232,9 +232,9 @@ DateTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts index 60112b9b92da0..1013150e535b1 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts @@ -3,7 +3,11 @@ import { DesktopDateTimePickerSlots, DesktopDateTimePickerSlotProps, } from '../DesktopDateTimePicker'; -import { BaseSingleInputFieldProps, DateOrTimeViewWithMeridiem } from '../internals/models'; +import { + BaseSingleInputFieldProps, + DateOrTimeViewWithMeridiem, + PickerValue, +} from '../internals/models'; import { MobileDateTimePickerProps, MobileDateTimePickerSlots, @@ -55,4 +59,4 @@ export interface DateTimePickerProps, or component). */ export type DateTimePickerFieldProps = ValidateDateTimeProps & - BaseSingleInputFieldProps; + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx index e91125595b6ee..b232a1882948d 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx @@ -17,7 +17,7 @@ import { DateTimePickerToolbarClasses, getDateTimePickerToolbarUtilityClass, } from './dateTimePickerToolbarClasses'; -import { DateOrTimeViewWithMeridiem, WrapperVariant } from '../internals/models'; +import { DateOrTimeViewWithMeridiem, PickerValue, WrapperVariant } from '../internals/models'; import { useMeridiemMode } from '../internals/hooks/date-helpers-hooks'; import { MULTI_SECTION_CLOCK_SECTION_WIDTH } from '../internals/constants/dimensions'; import { formatMeridiem } from '../internals/utils/date-utils'; @@ -34,7 +34,7 @@ export interface ExportedDateTimePickerToolbarProps extends ExportedBaseToolbarP export interface DateTimePickerToolbarProps extends ExportedDateTimePickerToolbarProps, - MakeOptional, 'view'> { + MakeOptional, 'view'> { toolbarVariant?: WrapperVariant; /** * If provided, it will be used instead of `dateTimePickerToolbarTitle` from localization. diff --git a/packages/x-date-pickers/src/DateTimePicker/shared.tsx b/packages/x-date-pickers/src/DateTimePicker/shared.tsx index 02328b6e28e3b..813f33f9c062e 100644 --- a/packages/x-date-pickers/src/DateTimePicker/shared.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/shared.tsx @@ -32,7 +32,7 @@ import { DateViewRendererProps } from '../dateViewRenderers'; import { TimeViewRendererProps } from '../timeViewRenderers'; import { applyDefaultViewProps } from '../internals/utils/views'; import { BaseClockProps, ExportedBaseClockProps } from '../internals/models/props/time'; -import { DateOrTimeViewWithMeridiem, TimeViewWithMeridiem } from '../internals/models'; +import { DateOrTimeViewWithMeridiem, PickerValue, TimeViewWithMeridiem } from '../internals/models'; export interface BaseDateTimePickerSlots extends DateCalendarSlots, TimeClockSlots { /** @@ -62,7 +62,7 @@ export type DateTimePickerViewRenderers< TView extends DateOrTimeViewWithMeridiem, TAdditionalProps extends {} = {}, > = PickerViewRendererLookup< - false, + PickerValue, TView, Omit, 'slots' | 'slotProps'> & Omit< @@ -73,7 +73,7 @@ export type DateTimePickerViewRenderers< >; export interface BaseDateTimePickerProps - extends BasePickerInputProps, + extends BasePickerInputProps, Omit, ExportedBaseClockProps, DateTimeValidationProps { diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index 155d79db0849f..f5f035ca05f00 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -218,17 +218,17 @@ DesktopDatePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -242,9 +242,9 @@ DesktopDatePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx b/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx index 7ef97fbb54352..1c79140c48074 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/tests/describes.DesktopDatePicker.test.tsx @@ -10,6 +10,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -41,7 +42,7 @@ describe(' - Describes', () => { ], })); - describeValue(DesktopDatePicker, () => ({ + describeValue(DesktopDatePicker, () => ({ render, componentFamily: 'picker', type: 'date', diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index b5d78017d6afe..3e7ba8dd66359 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -16,7 +16,7 @@ import { renderDateViewCalendar } from '../dateViewRenderers/dateViewRenderers'; import { usePickerTranslations } from '../hooks/usePickerTranslations'; import { useUtils } from '../internals/hooks/useUtils'; import { validateDateTime, extractValidationProps } from '../validation'; -import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { DateOrTimeViewWithMeridiem, PickerValue } from '../internals/models'; import { CalendarIcon } from '../icons'; import { UseDesktopPickerProps, useDesktopPicker } from '../internals/hooks/useDesktopPicker'; import { PickerViewsRendererProps } from '../internals/hooks/usePicker'; @@ -51,14 +51,14 @@ const rendererInterceptor = function rendererInterceptor< inViewRenderers: DateTimePickerViewRenderers, popperView: TView, rendererProps: PickerViewsRendererProps< - false, + PickerValue, TView, DefaultizedProps< UseDesktopPickerProps< TView, TEnableAccessibleFieldDOMStructure, any, - UsePickerViewsProps + UsePickerViewsProps >, 'openTo' >, @@ -391,17 +391,17 @@ DesktopDateTimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -415,9 +415,9 @@ DesktopDateTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx index 886c6c9ed47d9..5c9428f6bf009 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePickerLayout.tsx @@ -11,21 +11,22 @@ import { usePickerLayout, } from '../PickersLayout'; import { DateOrTimeViewWithMeridiem } from '../internals/models/common'; +import { PickerValidValue } from '../internals/models'; type DesktopDateTimePickerLayoutComponent = (< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, >( - props: PickersLayoutProps & React.RefAttributes, + props: PickersLayoutProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; /** * @ignore - internal component. */ const DesktopDateTimePickerLayout = React.forwardRef(function DesktopDateTimePickerLayout< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, ->(props: PickersLayoutProps, ref: React.Ref) { +>(props: PickersLayoutProps, ref: React.Ref) { const isRtl = useRtl(); const { toolbar, tabs, content, actionBar, shortcuts } = usePickerLayout(props); const { sx, className, isLandscape, classes } = props; @@ -121,7 +122,7 @@ DesktopDateTimePickerLayout.propTypes = { PropTypes.func, PropTypes.object, ]), - value: PropTypes.any, + value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), view: PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']), views: PropTypes.arrayOf( PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired, diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx index 07f87eeea3e31..5d6ab646c7b95 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/tests/describes.DesktopDateTimePicker.test.tsx @@ -1,3 +1,5 @@ +import * as React from 'react'; +import { expect } from 'chai'; import { fireEvent, screen } from '@mui/internal-test-utils'; import { createPickerRenderer, @@ -9,8 +11,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { DesktopDateTimePicker } from '@mui/x-date-pickers/DesktopDateTimePicker'; -import { expect } from 'chai'; -import * as React from 'react'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -54,7 +55,7 @@ describe(' - Describes', () => { ], })); - describeValue(DesktopDateTimePicker, () => ({ + describeValue(DesktopDateTimePicker, () => ({ render, componentFamily: 'picker', type: 'date-time', diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 35c1f980b55d4..75528d45cd42b 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -244,17 +244,17 @@ DesktopTimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -268,9 +268,9 @@ DesktopTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx b/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx index ca9ad873cd199..700a92a4156ff 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/tests/describes.DesktopTimePicker.test.tsx @@ -11,6 +11,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { DesktopTimePicker } from '@mui/x-date-pickers/DesktopTimePicker'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -46,7 +47,7 @@ describe(' - Describes', () => { ], })); - describeValue(DesktopTimePicker, () => ({ + describeValue(DesktopTimePicker, () => ({ render, componentFamily: 'picker', type: 'time', diff --git a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx index dd2e6132bb8f1..b9899f50a85db 100644 --- a/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx +++ b/packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx @@ -22,6 +22,7 @@ import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithT import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useClockReferenceDate } from '../internals/hooks/useClockReferenceDate'; import { getFocusedListItemIndex } from '../internals/utils/utils'; +import { PickerValue } from '../internals/models'; const useUtilityClasses = (ownerState: DigitalClockProps) => { const { classes } = ownerState; @@ -197,7 +198,7 @@ export const DigitalClock = React.forwardRef(function DigitalClock( handleRawValueChange(newValue, 'finish', 'hours'), ); - const { setValueAndGoToNextView } = useViews>({ + const { setValueAndGoToNextView } = useViews>({ view: inView, views, openTo, @@ -441,9 +442,9 @@ DigitalClock.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ diff --git a/packages/x-date-pickers/src/DigitalClock/tests/describes.DigitalClock.test.tsx b/packages/x-date-pickers/src/DigitalClock/tests/describes.DigitalClock.test.tsx index 845d744cfba51..c4f5013abc991 100644 --- a/packages/x-date-pickers/src/DigitalClock/tests/describes.DigitalClock.test.tsx +++ b/packages/x-date-pickers/src/DigitalClock/tests/describes.DigitalClock.test.tsx @@ -10,6 +10,7 @@ import { formatFullTimeValue, } from 'test/utils/pickers'; import { DigitalClock, digitalClockClasses as classes } from '@mui/x-date-pickers/DigitalClock'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -32,7 +33,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(DigitalClock, () => ({ + describeValue(DigitalClock, () => ({ render, componentFamily: 'digital-clock', type: 'time', diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 0519f7dc68996..90e9db74e87dc 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -215,17 +215,17 @@ MobileDatePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -239,9 +239,9 @@ MobileDatePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx b/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx index c53ef9a11e713..2a75c950b93df 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/tests/describes.MobileDatePicker.test.tsx @@ -11,6 +11,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -41,7 +42,7 @@ describe(' - Describes', () => { ], })); - describeValue(MobileDatePicker, () => ({ + describeValue(MobileDatePicker, () => ({ render, componentFamily: 'picker', type: 'date', diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 103e2428b01b1..cdc1c91a5abe8 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -268,17 +268,17 @@ MobileDateTimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -292,9 +292,9 @@ MobileDateTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx index b66a0c6a6d6eb..30ae63e192e42 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/tests/describes.MobileDateTimePicker.test.tsx @@ -12,6 +12,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { MobileDateTimePicker } from '@mui/x-date-pickers/MobileDateTimePicker'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -46,7 +47,7 @@ describe(' - Describes', () => { ], })); - describeValue(MobileDateTimePicker, () => ({ + describeValue(MobileDateTimePicker, () => ({ render, componentFamily: 'picker', type: 'date-time', diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index 52dbfe9a23c7d..4428a5c28a143 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -207,17 +207,17 @@ MobileTimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -231,9 +231,9 @@ MobileTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx b/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx index 9107bdf8486d7..5cff45ba0c9ce 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/tests/describes.MobileTimePicker.test.tsx @@ -13,6 +13,7 @@ import { getFieldInputRoot, } from 'test/utils/pickers'; import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -47,7 +48,7 @@ describe(' - Describes', () => { ], })); - describeValue(MobileTimePicker, () => ({ + describeValue(MobileTimePicker, () => ({ render, componentFamily: 'picker', type: 'time', diff --git a/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx b/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx index 5c726987d3202..9f9a3a8d903bc 100644 --- a/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx +++ b/packages/x-date-pickers/src/MonthCalendar/tests/describes.MonthCalendar.test.tsx @@ -8,6 +8,7 @@ import { describeValue, } from 'test/utils/pickers'; import { MonthCalendar, monthCalendarClasses as classes } from '@mui/x-date-pickers/MonthCalendar'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -29,7 +30,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(MonthCalendar, () => ({ + describeValue(MonthCalendar, () => ({ render, componentFamily: 'calendar', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-02-01')], diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx index 68295c6856f15..2dfcd41c1bd4d 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx @@ -21,7 +21,7 @@ import { } from './MultiSectionDigitalClock.types'; import { getHourSectionOptions, getTimeSectionOptions } from './MultiSectionDigitalClock.utils'; import { PickerValidDate, TimeStepOptions, TimeView } from '../models'; -import { TimeViewWithMeridiem } from '../internals/models'; +import { PickerValue, TimeViewWithMeridiem } from '../internals/models'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useClockReferenceDate } from '../internals/hooks/useClockReferenceDate'; @@ -153,7 +153,10 @@ export const MultiSectionDigitalClock = React.forwardRef(function MultiSectionDi return inViews.includes('meridiem') ? inViews : [...inViews, 'meridiem']; }, [ampm, inViews]); - const { view, setValueAndGoToNextView, focusedView } = useViews({ + const { view, setValueAndGoToNextView, focusedView } = useViews< + PickerValue, + TimeViewWithMeridiem + >({ view: inView, views, openTo, @@ -517,9 +520,9 @@ MultiSectionDigitalClock.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ diff --git a/packages/x-date-pickers/src/MultiSectionDigitalClock/tests/describes.MultiSectionDigitalClock.test.tsx b/packages/x-date-pickers/src/MultiSectionDigitalClock/tests/describes.MultiSectionDigitalClock.test.tsx index 469fcad2a4753..3ab127d6bafa6 100644 --- a/packages/x-date-pickers/src/MultiSectionDigitalClock/tests/describes.MultiSectionDigitalClock.test.tsx +++ b/packages/x-date-pickers/src/MultiSectionDigitalClock/tests/describes.MultiSectionDigitalClock.test.tsx @@ -12,7 +12,7 @@ import { MultiSectionDigitalClock, multiSectionDigitalClockClasses as classes, } from '@mui/x-date-pickers/MultiSectionDigitalClock'; -import { formatMeridiem } from '@mui/x-date-pickers/internals'; +import { formatMeridiem, PickerValue } from '@mui/x-date-pickers/internals'; import { describeConformance } from 'test/utils/describeConformance'; describe(' - Describes', () => { @@ -35,7 +35,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(MultiSectionDigitalClock, () => ({ + describeValue(MultiSectionDigitalClock, () => ({ render, componentFamily: 'multi-section-digital-clock', type: 'time', diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx index 1dcd9ed1628c9..2c9fbc0e84176 100644 --- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx +++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx @@ -7,7 +7,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { PickersLayoutProps } from './PickersLayout.types'; import { pickersLayoutClasses, getPickersLayoutUtilityClass } from './pickersLayoutClasses'; import usePickerLayout from './usePickerLayout'; -import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../internals/models'; const useUtilityClasses = (ownerState: PickersLayoutProps) => { const { isLandscape, classes } = ownerState; @@ -79,8 +79,11 @@ export const PickersLayoutContentWrapper = styled('div', { flexDirection: 'column', }); -type PickersLayoutComponent = (( - props: PickersLayoutProps & React.RefAttributes, +type PickersLayoutComponent = (< + TValue extends PickerValidValue, + TView extends DateOrTimeViewWithMeridiem, +>( + props: PickersLayoutProps & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; /** @@ -93,9 +96,9 @@ type PickersLayoutComponent = ((inProps: PickersLayoutProps, ref: React.Ref) { +>(inProps: PickersLayoutProps, ref: React.Ref) { const props = useThemeProps({ props: inProps, name: 'MuiPickersLayout' }); const { toolbar, content, tabs, actionBar, shortcuts } = usePickerLayout(props); @@ -191,7 +194,7 @@ PickersLayout.propTypes = { PropTypes.func, PropTypes.object, ]), - value: PropTypes.any, + value: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), view: PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']), views: PropTypes.arrayOf( PropTypes.oneOf(['day', 'hours', 'meridiem', 'minutes', 'month', 'seconds', 'year']).isRequired, diff --git a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts index 093f425d93f76..007753e0ead31 100644 --- a/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts +++ b/packages/x-date-pickers/src/PickersLayout/PickersLayout.types.ts @@ -13,10 +13,10 @@ import { PickersShortcuts, } from '../PickersShortcuts/PickersShortcuts'; import { PickerOwnerState } from '../models'; -import { InferPickerValue } from '../internals/models'; +import { PickerValidValue } from '../internals/models'; export interface ExportedPickersLayoutSlots< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > { /** @@ -28,13 +28,13 @@ export interface ExportedPickersLayoutSlots< * Custom component for the shortcuts. * @default PickersShortcuts */ - shortcuts?: React.JSXElementConstructor>; + shortcuts?: React.JSXElementConstructor>; /** * Custom component for wrapping the layout. * It wraps the toolbar, views, action bar, and shortcuts. */ layout?: React.JSXElementConstructor< - PickersLayoutProps & React.RefAttributes + PickersLayoutProps & React.RefAttributes >; } @@ -44,7 +44,7 @@ export interface PickerLayoutOwnerState extends PickerOwnerState { } export interface ExportedPickersLayoutSlotProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > { /** @@ -58,13 +58,13 @@ export interface ExportedPickersLayoutSlotProps< /** * Props passed down to the layoutRoot component. */ - layout?: Partial>; + layout?: Partial>; } export interface PickersLayoutSlots< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends ExportedPickersLayoutSlots { +> extends ExportedPickersLayoutSlots { /** * Tabs enabling toggling between views. */ @@ -73,13 +73,13 @@ export interface PickersLayoutSlots< * Custom component for the toolbar. * It is placed above the picker views. */ - toolbar?: React.JSXElementConstructor>; + toolbar?: React.JSXElementConstructor>; } export interface PickersLayoutSlotProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends ExportedPickersLayoutSlotProps { +> extends ExportedPickersLayoutSlotProps { /** * Props passed down to the tabs component. */ @@ -91,10 +91,9 @@ export interface PickersLayoutSlotProps< } export interface PickersLayoutProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends Omit, 'value'> { - value?: InferPickerValue; +> extends UsePickerLayoutPropsResponseLayoutProps { className?: string; children?: React.ReactNode; /** @@ -109,22 +108,22 @@ export interface PickersLayoutProps< * Overridable component slots. * @default {} */ - slots?: PickersLayoutSlots; + slots?: PickersLayoutSlots; /** * The props used for each component slot. * @default {} */ - slotProps?: PickersLayoutSlotProps; + slotProps?: PickersLayoutSlotProps; /** * `true` if the application is in right-to-left direction. */ isRtl: boolean; } -export interface SubComponents { +export interface SubComponents { toolbar: React.ReactElement | null; content: React.ReactNode; tabs: React.ReactElement | null; actionBar: React.ReactElement; - shortcuts: React.ReactElement> | null; + shortcuts: React.ReactElement> | null; } diff --git a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx index bddf6e3e219a9..9fb75c8dc4355 100644 --- a/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx +++ b/packages/x-date-pickers/src/PickersLayout/usePickerLayout.tsx @@ -7,12 +7,12 @@ import { PickerLayoutOwnerState, PickersLayoutProps, SubComponents } from './Pic import { getPickersLayoutUtilityClass, PickersLayoutClasses } from './pickersLayoutClasses'; import { PickersShortcuts } from '../PickersShortcuts'; import { BaseToolbarProps } from '../internals/models/props/toolbar'; -import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../internals/models'; import { usePickerPrivateContext } from '../internals/hooks/usePickerPrivateContext'; -function toolbarHasView( - toolbarProps: BaseToolbarProps | any, -): toolbarProps is BaseToolbarProps { +function toolbarHasView( + toolbarProps: BaseToolbarProps | any, +): toolbarProps is BaseToolbarProps { return toolbarProps.view !== null; } @@ -34,11 +34,11 @@ const useUtilityClasses = ( return composeClasses(slots, getPickersLayoutUtilityClass, classes); }; -interface UsePickerLayoutResponse extends SubComponents {} +interface UsePickerLayoutResponse extends SubComponents {} -const usePickerLayout = ( - props: PickersLayoutProps, -): UsePickerLayoutResponse => { +const usePickerLayout = ( + props: PickersLayoutProps, +): UsePickerLayoutResponse => { const { ownerState: pickersOwnerState } = usePickerPrivateContext(); const { diff --git a/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx b/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx index 1b6c822bb444e..3a2f284211398 100644 --- a/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx +++ b/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx @@ -5,15 +5,15 @@ import List, { ListProps } from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import Chip from '@mui/material/Chip'; import { VIEW_HEIGHT } from '../internals/constants/dimensions'; -import { InferPickerValue } from '../internals/models'; +import { PickerValidValue } from '../internals/models'; -interface PickersShortcutsItemGetValueParams { - isValid: (value: InferPickerValue) => boolean; +interface PickersShortcutsItemGetValueParams { + isValid: (value: TValue) => boolean; } -export interface PickersShortcutsItem { +export interface PickersShortcutsItem { label: string; - getValue: (params: PickersShortcutsItemGetValueParams) => InferPickerValue; + getValue: (params: PickersShortcutsItemGetValueParams) => TValue; /** * Identifier of the shortcut. * If provided, it will be used as the key of the shortcut. @@ -21,18 +21,18 @@ export interface PickersShortcutsItem { id?: string; } -export type PickersShortcutsItemContext = Omit, 'getValue'>; +export type PickersShortcutsItemContext = Omit, 'getValue'>; export type PickerShortcutChangeImportance = 'set' | 'accept'; -export interface ExportedPickersShortcutProps +export interface ExportedPickersShortcutProps extends Omit { /** * Ordered array of shortcuts to display. * If empty, does not display the shortcuts. * @default [] */ - items?: PickersShortcutsItem[]; + items?: PickersShortcutsItem[]; /** * Importance of the change when picking a shortcut: * - "accept": fires `onChange`, fires `onAccept` and closes the picker. @@ -42,15 +42,15 @@ export interface ExportedPickersShortcutProps changeImportance?: PickerShortcutChangeImportance; } -export interface PickersShortcutsProps - extends ExportedPickersShortcutProps { +export interface PickersShortcutsProps + extends ExportedPickersShortcutProps { isLandscape: boolean; onChange: ( - newValue: InferPickerValue, + newValue: TValue, changeImportance: PickerShortcutChangeImportance, shortcut: PickersShortcutsItemContext, ) => void; - isValid: (value: InferPickerValue) => boolean; + isValid: (value: TValue) => boolean; } /** @@ -62,7 +62,7 @@ export interface PickersShortcutsProps * * - [PickersShortcuts API](https://mui.com/x/api/date-pickers/pickers-shortcuts/) */ -function PickersShortcuts(props: PickersShortcutsProps) { +function PickersShortcuts(props: PickersShortcutsProps) { const { items, changeImportance = 'accept', isLandscape, onChange, isValid, ...other } = props; if (items == null || items.length === 0) { diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx index 0afc8292e9f11..d7a5e18afdbb1 100644 --- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx +++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx @@ -155,17 +155,17 @@ StaticDatePicker.propTypes = { monthsPerRow: PropTypes.oneOf([3, 4]), /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -180,9 +180,9 @@ StaticDatePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 a169f0faf6180..301852e0ff4dd 100644 --- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx @@ -207,17 +207,17 @@ StaticDateTimePicker.propTypes = { monthsPerRow: PropTypes.oneOf([3, 4]), /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -232,9 +232,9 @@ StaticDateTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 0123d9ce3781e..44341686e4fef 100644 --- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx +++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx @@ -145,17 +145,17 @@ StaticTimePicker.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -170,9 +170,9 @@ StaticTimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx index a315c7257e7f0..92ea960f66892 100644 --- a/packages/x-date-pickers/src/TimeClock/TimeClock.tsx +++ b/packages/x-date-pickers/src/TimeClock/TimeClock.tsx @@ -20,6 +20,7 @@ import { getHourNumbers, getMinutesNumbers } from './ClockNumbers'; import { useControlledValueWithTimezone } from '../internals/hooks/useValueWithTimezone'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { useClockReferenceDate } from '../internals/hooks/useClockReferenceDate'; +import { PickerValue } from '../internals/models'; const useUtilityClasses = (ownerState: TimeClockProps) => { const { classes } = ownerState; @@ -130,7 +131,7 @@ export const TimeClock = React.forwardRef(function TimeClock( const now = useNow(timezone); const { view, setView, previousView, nextView, setValueAndGoToNextView } = useViews< - false, + PickerValue, TimeView >({ view: inView, @@ -467,9 +468,9 @@ TimeClock.propTypes = { minutesStep: PropTypes.number, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ diff --git a/packages/x-date-pickers/src/TimeClock/tests/describes.TimeClock.test.tsx b/packages/x-date-pickers/src/TimeClock/tests/describes.TimeClock.test.tsx index 9cf6545bbce72..140d667a2938f 100644 --- a/packages/x-date-pickers/src/TimeClock/tests/describes.TimeClock.test.tsx +++ b/packages/x-date-pickers/src/TimeClock/tests/describes.TimeClock.test.tsx @@ -13,6 +13,7 @@ import { describeValue, } from 'test/utils/pickers'; import { describeConformance } from 'test/utils/describeConformance'; +import { PickerValue } from '@mui/x-date-pickers/internals'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer(); @@ -26,7 +27,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(TimeClock, () => ({ + describeValue(TimeClock, () => ({ render, componentFamily: 'clock', values: [adapterToUse.date('2018-01-01T12:30:00'), adapterToUse.date('2018-01-01T13:35:00')], diff --git a/packages/x-date-pickers/src/TimeField/TimeField.tsx b/packages/x-date-pickers/src/TimeField/TimeField.tsx index d0335a2e37789..b84ff450fa901 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.tsx +++ b/packages/x-date-pickers/src/TimeField/TimeField.tsx @@ -216,9 +216,9 @@ TimeField.propTypes = { onBlur: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -231,9 +231,9 @@ TimeField.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with 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 907332c7fd713..9767d48f47d14 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.types.ts +++ b/packages/x-date-pickers/src/TimeField/TimeField.types.ts @@ -11,10 +11,11 @@ import { } from '../hooks/useClearableField'; import { ExportedValidateTimeProps } from '../validation/validateTime'; import { AmPmProps } from '../internals/models/props/time'; +import { PickerValue } from '../internals/models'; export interface UseTimeFieldProps extends MakeOptional< - UseFieldInternalProps, + UseFieldInternalProps, 'format' >, ExportedValidateTimeProps, diff --git a/packages/x-date-pickers/src/TimeField/tests/describes.TimeField.test.tsx b/packages/x-date-pickers/src/TimeField/tests/describes.TimeField.test.tsx index dfc22c31bbac5..515cbd0b2639c 100644 --- a/packages/x-date-pickers/src/TimeField/tests/describes.TimeField.test.tsx +++ b/packages/x-date-pickers/src/TimeField/tests/describes.TimeField.test.tsx @@ -11,6 +11,7 @@ import { import { TimeField } from '@mui/x-date-pickers/TimeField'; import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; import { describeConformance } from 'test/utils/describeConformance'; +import { PickerValue } from '@mui/x-date-pickers/internals'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ clock: 'fake' }); @@ -31,7 +32,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants', 'themeStyleOverrides'], })); - describeValue(TimeField, () => ({ + describeValue(TimeField, () => ({ render, componentFamily: 'field', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-02')], diff --git a/packages/x-date-pickers/src/TimeField/useTimeField.ts b/packages/x-date-pickers/src/TimeField/useTimeField.ts index 601d593fe0b61..51a88016a8dc3 100644 --- a/packages/x-date-pickers/src/TimeField/useTimeField.ts +++ b/packages/x-date-pickers/src/TimeField/useTimeField.ts @@ -8,6 +8,7 @@ import { UseTimeFieldProps } from './TimeField.types'; import { validateTime } from '../validation'; import { useSplitFieldProps } from '../hooks'; import { useDefaultizedTimeField } from '../internals/hooks/defaultizedFieldProps'; +import { PickerValue } from '../internals/models'; export const useTimeField = < TEnableAccessibleFieldDOMStructure extends boolean, @@ -23,7 +24,7 @@ export const useTimeField = < const { forwardedProps, internalProps } = useSplitFieldProps(props, 'time'); return useField< - false, + PickerValue, TEnableAccessibleFieldDOMStructure, typeof forwardedProps, typeof internalProps diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx index 27f8f244d4fde..6b3b60669aed6 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx @@ -154,17 +154,17 @@ TimePicker.propTypes = { name: PropTypes.string, /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onAccept: PropTypes.func, /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ onChange: PropTypes.func, @@ -178,9 +178,9 @@ TimePicker.propTypes = { * 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ onError: PropTypes.func, /** diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts index 192d9c72cd516..03ce715b6e850 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts @@ -3,7 +3,7 @@ import { DesktopTimePickerSlots, DesktopTimePickerSlotProps, } from '../DesktopTimePicker'; -import { BaseSingleInputFieldProps, TimeViewWithMeridiem } from '../internals/models'; +import { BaseSingleInputFieldProps, PickerValue, TimeViewWithMeridiem } from '../internals/models'; import { MobileTimePickerProps, MobileTimePickerSlots, @@ -46,4 +46,4 @@ export interface TimePickerProps = ValidateTimeProps & - BaseSingleInputFieldProps; + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx index 9ed56ef9f2a4b..bbc3c77e1bc19 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx +++ b/packages/x-date-pickers/src/TimePicker/TimePickerToolbar.tsx @@ -18,12 +18,12 @@ import { timePickerToolbarClasses, TimePickerToolbarClasses, } from './timePickerToolbarClasses'; -import { TimeViewWithMeridiem } from '../internals/models'; +import { PickerValue, TimeViewWithMeridiem } from '../internals/models'; import { formatMeridiem } from '../internals/utils/date-utils'; import { PickerValidDate } from '../models'; export interface TimePickerToolbarProps - extends BaseToolbarProps, + extends BaseToolbarProps, ExportedTimePickerToolbarProps { ampm?: boolean; ampmInClock?: boolean; diff --git a/packages/x-date-pickers/src/TimePicker/shared.tsx b/packages/x-date-pickers/src/TimePicker/shared.tsx index f8660a447a9e0..ff73b36126e98 100644 --- a/packages/x-date-pickers/src/TimePicker/shared.tsx +++ b/packages/x-date-pickers/src/TimePicker/shared.tsx @@ -16,7 +16,7 @@ import { PickerViewRendererLookup } from '../internals/hooks/usePicker/usePicker import { TimeViewRendererProps } from '../timeViewRenderers'; import { applyDefaultViewProps } from '../internals/utils/views'; import { BaseClockProps, ExportedBaseClockProps } from '../internals/models/props/time'; -import { TimeViewWithMeridiem } from '../internals/models'; +import { PickerValue, TimeViewWithMeridiem } from '../internals/models'; export interface BaseTimePickerSlots extends TimeClockSlots { /** @@ -34,14 +34,14 @@ export type TimePickerViewRenderers< TView extends TimeViewWithMeridiem, TAdditionalProps extends {} = {}, > = PickerViewRendererLookup< - false, + PickerValue, TView, TimeViewRendererProps>, TAdditionalProps >; export interface BaseTimePickerProps - extends BasePickerInputProps, + extends BasePickerInputProps, ExportedBaseClockProps { /** * Display ampm controls under the clock (instead of in the toolbar). diff --git a/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx b/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx index b661a114096af..448cbb8fe5996 100644 --- a/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx +++ b/packages/x-date-pickers/src/YearCalendar/tests/describes.YearCalendar.test.tsx @@ -9,6 +9,7 @@ import { describeValue, } from 'test/utils/pickers'; import { describeConformance } from 'test/utils/describeConformance'; +import { PickerValue } from '@mui/x-date-pickers/internals'; describe(' - Describes', () => { const { render, clock } = createPickerRenderer({ @@ -31,7 +32,7 @@ describe(' - Describes', () => { skip: ['componentProp', 'componentsProp', 'themeVariants'], })); - describeValue(YearCalendar, () => ({ + describeValue(YearCalendar, () => ({ render, componentFamily: 'calendar', values: [adapterToUse.date('2018-01-01'), adapterToUse.date('2018-01-01')], diff --git a/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx b/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx index 9c868b0c81d4a..fd9acbb88680c 100644 --- a/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersToolbar.tsx @@ -5,12 +5,12 @@ import { styled, useThemeProps } from '@mui/material/styles'; import composeClasses from '@mui/utils/composeClasses'; import { BaseToolbarProps } from '../models/props/toolbar'; import { getPickersToolbarUtilityClass, PickersToolbarClasses } from './pickersToolbarClasses'; -import { DateOrTimeViewWithMeridiem } from '../models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../models'; export interface PickersToolbarProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends Pick, 'isLandscape' | 'hidden' | 'titleId'> { +> extends Pick, 'isLandscape' | 'hidden' | 'titleId'> { className?: string; landscapeDirection?: 'row' | 'column'; toolbarTitle: React.ReactNode; @@ -87,18 +87,18 @@ const PickersToolbarContent = styled('div', { }); type PickersToolbarComponent = (< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, >( - props: React.PropsWithChildren> & + props: React.PropsWithChildren> & React.RefAttributes, ) => React.JSX.Element) & { propTypes?: any }; export const PickersToolbar = React.forwardRef(function PickersToolbar< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, >( - inProps: React.PropsWithChildren>, + inProps: React.PropsWithChildren>, ref: React.Ref, ) { const props = useThemeProps({ props: inProps, name: 'MuiPickersToolbar' }); 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 cfb3e7c4abe35..78d469890463c 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -9,7 +9,7 @@ import { UseDesktopPickerParams, UseDesktopPickerProps } from './useDesktopPicke import { usePicker } from '../usePicker'; import { PickersLayout } from '../../../PickersLayout'; import { FieldRef, InferError } from '../../../models'; -import { DateOrTimeViewWithMeridiem, BaseSingleInputFieldProps } from '../../models'; +import { DateOrTimeViewWithMeridiem, BaseSingleInputFieldProps, PickerValue } from '../../models'; import { PickerProvider } from '../../components/PickerProvider'; /** @@ -54,7 +54,7 @@ export const useDesktopPicker = < } = props; const containerRef = React.useRef(null); - const fieldRef = React.useRef>(null); + const fieldRef = React.useRef>(null); const labelId = useId(); const isToolbarHidden = innerSlotProps?.toolbar?.hidden ?? false; @@ -69,7 +69,7 @@ export const useDesktopPicker = < shouldRestoreFocus, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, fieldRef, @@ -111,7 +111,7 @@ export const useDesktopPicker = < const Field = slots.field; const fieldProps: BaseSingleInputFieldProps< - false, + PickerValue, TEnableAccessibleFieldDOMStructure, InferError > = useSlotProps({ diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts index e72875c21e9fd..555db1d6308fb 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.types.ts @@ -19,7 +19,7 @@ import { } from '../../../PickersLayout/PickersLayout.types'; import { UsePickerValueNonStaticProps } from '../usePicker/usePickerValue.types'; import { UsePickerViewsNonStaticProps, UsePickerViewsProps } from '../usePicker/usePickerViews'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValue } from '../../models'; import { UseClearableFieldSlots, UseClearableFieldSlotProps, @@ -30,7 +30,7 @@ export interface UseDesktopPickerSlots PickersPopperSlots, 'desktopPaper' | 'desktopTransition' | 'desktopTrapFocus' | 'popper' >, - ExportedPickersLayoutSlots, + ExportedPickersLayoutSlots, UseClearableFieldSlots { /** * Component used to enter the date with the keyboard. @@ -61,16 +61,16 @@ export interface UseDesktopPickerSlotProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, > extends ExportedUseDesktopPickerSlotProps, - Pick, 'toolbar'> {} + Pick, 'toolbar'> {} export interface ExportedUseDesktopPickerSlotProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, > extends PickersPopperSlotProps, - ExportedPickersLayoutSlotProps, + ExportedPickersLayoutSlotProps, UseClearableFieldSlotProps { field?: SlotComponentPropsFromProps< - PickerFieldSlotProps, + PickerFieldSlotProps, {}, PickerOwnerState >; @@ -96,8 +96,8 @@ export interface UseDesktopPickerProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, + TExternalProps extends UsePickerViewsProps, +> extends BasePickerProps, MakeRequired { /** * Overridable component slots. @@ -121,7 +121,7 @@ export interface UseDesktopPickerParams< TExternalProps >, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' | 'rendererInterceptor' > { props: TExternalProps; 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 157777b5384fd..8bec0c4e9afa6 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts @@ -19,22 +19,19 @@ import { useFieldState } from './useFieldState'; import { useFieldCharacterEditing } from './useFieldCharacterEditing'; import { useFieldV7TextField } from './useFieldV7TextField'; import { useFieldV6TextField } from './useFieldV6TextField'; +import { PickerValidValue } from '../../models'; export const useField = < - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TForwardedProps extends UseFieldCommonForwardedProps & UseFieldForwardedProps, - TInternalProps extends UseFieldInternalProps< - TIsRange, - TEnableAccessibleFieldDOMStructure, - any - > & { + TInternalProps extends UseFieldInternalProps & { minutesStep?: number; }, >( params: UseFieldParams< - TIsRange, + TValue, TEnableAccessibleFieldDOMStructure, TForwardedProps, TInternalProps @@ -74,7 +71,7 @@ export const useField = < timezone, } = stateResponse; - const characterEditingResponse = useFieldCharacterEditing({ + const characterEditingResponse = useFieldCharacterEditing({ sections: state.sections, updateSectionValue, sectionsValueBoundaries, 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 50bbcd8aeb15a..70229c56019fb 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 @@ -19,39 +19,39 @@ import type { UseFieldStateResponse } from './useFieldState'; import type { UseFieldCharacterEditingResponse } from './useFieldCharacterEditing'; import { PickersSectionElement, PickersSectionListRef } from '../../../PickersSectionList'; import { ExportedUseClearableFieldProps } from '../../../hooks/useClearableField'; -import { FormProps, InferNonNullablePickerValue, InferPickerValue } from '../../models'; +import { FormProps, InferNonNullablePickerValue, PickerValidValue } from '../../models'; export interface UseFieldParams< - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TForwardedProps extends UseFieldCommonForwardedProps & UseFieldForwardedProps, - TInternalProps extends UseFieldInternalProps, + TInternalProps extends UseFieldInternalProps, > { forwardedProps: TForwardedProps; internalProps: TInternalProps; - valueManager: PickerValueManager>; - fieldValueManager: FieldValueManager; - validator: Validator, TInternalProps>; + valueManager: PickerValueManager>; + fieldValueManager: FieldValueManager; + validator: Validator, TInternalProps>; valueType: PickerValueType; } export interface UseFieldInternalProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TError, > extends TimezoneProps, FormProps, - OnErrorProps { + OnErrorProps { /** * The selected value. * Used when the component is controlled. */ - value?: InferPickerValue; + value?: TValue; /** * The default value. Use when the component is not controlled. */ - defaultValue?: InferPickerValue; + defaultValue?: TValue; /** * The date used to generate a part of the new value that is not present in the format when both `value` and `defaultValue` are empty. * For example, on time fields it will be used to determine the date to set. @@ -60,12 +60,12 @@ export interface UseFieldInternalProps< referenceDate?: PickerValidDate; /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ - onChange?: FieldChangeHandler; + onChange?: FieldChangeHandler; /** * Format of the date when rendered in the input(s). */ @@ -109,7 +109,7 @@ export interface UseFieldInternalProps< /** * The ref object used to imperatively interact with the field. */ - unstableFieldRef?: React.Ref>; + unstableFieldRef?: React.Ref>; /** * @default true */ @@ -205,8 +205,8 @@ export type FieldSectionsBoundaries = { }; }; -export type FieldChangeHandler = ( - value: InferPickerValue, +export type FieldChangeHandler = ( + value: TValue, context: FieldChangeHandlerContext, ) => void; @@ -218,7 +218,7 @@ export interface FieldChangeHandlerContext { * Object used to access and update the active date (i.e: the date containing the active section). * Mainly useful in the range fields where we need to update the date containing the active section without impacting the other one. */ -interface FieldActiveDateManager { +interface FieldActiveDateManager { /** * Active date from `state.value`. */ @@ -228,113 +228,113 @@ interface FieldActiveDateManager { */ referenceDate: PickerValidDate; /** - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. - * @param {InferFieldSection[]} sections The sections of the full value. - * @returns {InferFieldSection[]} The sections of the active date. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. + * @param {InferFieldSection[]} sections The sections of the full value. + * @returns {InferFieldSection[]} The sections of the active date. * Get the sections of the active date. */ - getSections: (sections: InferFieldSection[]) => InferFieldSection[]; + getSections: (sections: InferFieldSection[]) => InferFieldSection[]; /** * Creates the new value and reference value based on the new active date and the current state. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {PickerValidDate | null} newActiveDate The new value of the date containing the active section. - * @returns {Pick, 'value' | 'referenceValue'>} The new value and reference value to publish and store in the state. + * @returns {Pick, 'value' | 'referenceValue'>} The new value and reference value to publish and store in the state. */ getNewValuesFromNewActiveDate: ( newActiveDate: PickerValidDate | null, - ) => Pick, 'value' | 'referenceValue'>; + ) => Pick, 'value' | 'referenceValue'>; } export type FieldParsedSelectedSections = number | 'all' | null; -export interface FieldValueManager { +export interface FieldValueManager { /** * Creates the section list from the current value. * The `prevSections` are used on the range fields to avoid losing the sections of a partially filled date when editing the other date. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The utils to manipulate the date. - * @param {InferPickerValue} value The current value to generate sections from. - * @param {InferFieldSection[] | null} fallbackSections The sections to use as a fallback if a date is null or invalid. + * @param {TValue} value The current value to generate sections from. + * @param {InferFieldSection[] | null} fallbackSections The sections to use as a fallback if a date is null or invalid. * @param {(date: PickerValidDate) => FieldSection[]} getSectionsFromDate Returns the sections of the given date. - * @returns {InferFieldSection[]} The new section list. + * @returns {InferFieldSection[]} The new section list. */ getSectionsFromValue: ( utils: MuiPickersAdapter, - value: InferPickerValue, - fallbackSections: InferFieldSection[] | null, + value: TValue, + fallbackSections: InferFieldSection[] | null, getSectionsFromDate: (date: PickerValidDate) => FieldSection[], - ) => InferFieldSection[]; + ) => InferFieldSection[]; /** * Creates the string value to render in the input based on the current section list. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. - * @param {InferFieldSection[]} sections The current section list. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. + * @param {InferFieldSection[]} sections The current section list. * @param {string} localizedDigits The conversion table from localized to 0-9 digits. * @param {boolean} isRtl `true` if the current orientation is "right to left" * @returns {string} The string value to render in the input. */ getV6InputValueFromSections: ( - sections: InferFieldSection[], + sections: InferFieldSection[], localizedDigits: string[], isRtl: boolean, ) => string; /** * Creates the string value to render in the input based on the current section list. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. - * @param {InferFieldSection[]} sections The current section list. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. + * @param {InferFieldSection[]} sections The current section list. * @returns {string} The string value to render in the input. */ - getV7HiddenInputValueFromSections: (sections: InferFieldSection[]) => string; + getV7HiddenInputValueFromSections: (sections: InferFieldSection[]) => string; /** * Returns the manager of the active date. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The utils to manipulate the date. - * @param {UseFieldState} state The current state of the field. - * @param {InferFieldSection} activeSection The active section. - * @returns {FieldActiveDateManager} The manager of the active date. + * @param {UseFieldState} state The current state of the field. + * @param {InferFieldSection} activeSection The active section. + * @returns {FieldActiveDateManager} The manager of the active date. */ getActiveDateManager: ( utils: MuiPickersAdapter, - state: UseFieldState, - activeSection: InferFieldSection, - ) => FieldActiveDateManager; + state: UseFieldState, + activeSection: InferFieldSection, + ) => FieldActiveDateManager; /** * Parses a string version (most of the time coming from the input). * This method should only be used when the change does not come from a single section. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {string} valueStr The string value to parse. - * @param {InferPickerValue} referenceValue The reference value currently stored in state. + * @param {TValue} referenceValue The reference value currently stored in state. * @param {(dateStr: string, referenceDate: PickerValidDate) => PickerValidDate | null} parseDate A method to convert a string date into a parsed one. - * @returns {InferPickerValue} The new parsed value. + * @returns {TValue} The new parsed value. */ parseValueStr: ( valueStr: string, - referenceValue: InferNonNullablePickerValue, + referenceValue: InferNonNullablePickerValue, parseDate: (dateStr: string, referenceDate: PickerValidDate) => PickerValidDate | null, - ) => InferPickerValue; + ) => TValue; /** * Update the reference value with the new value. * This method must make sure that no date inside the returned `referenceValue` is invalid. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The utils to manipulate the date. - * @param {InferPickerValue} value The new value from which we want to take all valid dates in the `referenceValue` state. - * @param {InferPickerValue} prevReferenceValue The previous reference value. It is used as a fallback for invalid dates in the new value. - * @returns {InferPickerValue} The new reference value with no invalid date. + * @param {TValue} value The new value from which we want to take all valid dates in the `referenceValue` state. + * @param {TValue} prevReferenceValue The previous reference value. It is used as a fallback for invalid dates in the new value. + * @returns {TValue} The new reference value with no invalid date. */ updateReferenceValue: ( utils: MuiPickersAdapter, - value: InferPickerValue, - prevReferenceValue: InferNonNullablePickerValue, - ) => InferNonNullablePickerValue; + value: TValue, + prevReferenceValue: InferNonNullablePickerValue, + ) => InferNonNullablePickerValue; } -export interface UseFieldState { - value: InferPickerValue; +export interface UseFieldState { + value: TValue; /** * Non-nullable value used to keep trace of the timezone and the date parts not present in the format. * It is updated whenever we have a valid date (for the range picker we update only the portion of the range that is valid). */ - referenceValue: InferNonNullablePickerValue; - sections: InferFieldSection[]; + referenceValue: InferNonNullablePickerValue; + sections: InferFieldSection[]; /** * Android `onChange` behavior when the input selection is not empty is quite different from a desktop behavior. * There are two `onChange` calls: @@ -413,20 +413,16 @@ export interface UseFieldTextFieldInteractions { } export type UseFieldTextField = < - TIsRange extends boolean, + TValue extends PickerValidValue, TForwardedProps extends TEnableAccessibleFieldDOMStructure extends false ? UseFieldV6ForwardedProps : UseFieldV7ForwardedProps, - TInternalProps extends UseFieldInternalProps< - TIsRange, - TEnableAccessibleFieldDOMStructure, - any - > & { + TInternalProps extends UseFieldInternalProps & { minutesStep?: number; }, >( params: UseFieldTextFieldParams< - TIsRange, + TValue, TEnableAccessibleFieldDOMStructure, TForwardedProps, TInternalProps @@ -439,19 +435,19 @@ export type UseFieldTextField, + TInternalProps extends UseFieldInternalProps, > extends UseFieldParams< - TIsRange, + TValue, TEnableAccessibleFieldDOMStructure, TForwardedProps, TInternalProps >, - UseFieldStateResponse, + UseFieldStateResponse, UseFieldCharacterEditingResponse { areAllSectionsEmpty: boolean; sectionOrder: SectionOrdering; diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts index 2bebe3892fdb8..65324fa47abdc 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts @@ -18,6 +18,7 @@ import { InferFieldSection, } from '../../../models'; import { getMonthsInYear } from '../../utils/date-utils'; +import { PickerValidValue } from '../../models'; export const getDateSectionConfigFromFormatToken = ( utils: MuiPickersAdapter, @@ -231,10 +232,10 @@ export const cleanDigitSectionValue = ( return applyLocalizedDigits(valueStr, localizedDigits); }; -export const adjustSectionValue = ( +export const adjustSectionValue = ( utils: MuiPickersAdapter, timezone: PickersTimezone, - section: InferFieldSection, + section: InferFieldSection, keyCode: AvailableAdjustKeyCode, sectionsValueBoundaries: FieldSectionsValueBoundaries, localizedDigits: string[], @@ -615,8 +616,8 @@ export const getSectionsBoundaries = ( let warnedOnceInvalidSection = false; -export const validateSections = ( - sections: InferFieldSection[], +export const validateSections = ( + sections: InferFieldSection[], valueType: PickerValueType, ) => { if (process.env.NODE_ENV !== 'production') { diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts index 5c890b8f4b467..a348d3a396b65 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts @@ -20,6 +20,7 @@ import { isStringNumber, } from './useField.utils'; import { UpdateSectionValueParams } from './useFieldState'; +import { PickerValidValue } from '../../models'; interface CharacterEditingQuery { value: string; @@ -32,9 +33,9 @@ export interface ApplyCharacterEditingParams { sectionIndex: number; } -interface UseFieldCharacterEditingParams { - sections: InferFieldSection[]; - updateSectionValue: (params: UpdateSectionValueParams) => void; +interface UseFieldCharacterEditingParams { + sections: InferFieldSection[]; + updateSectionValue: (params: UpdateSectionValueParams) => void; sectionsValueBoundaries: FieldSectionsValueBoundaries; localizedDigits: string[]; setTempAndroidValueStr: (newValue: string | null) => void; @@ -70,15 +71,15 @@ type CharacterEditingApplier = ( * If it returns `{ saveQuery: false }, * Then we do nothing. */ -type QueryApplier = ( +type QueryApplier = ( queryValue: string, - activeSection: InferFieldSection, + activeSection: InferFieldSection, ) => { sectionValue: string; shouldGoToNextSection: boolean } | { saveQuery: boolean }; const QUERY_LIFE_DURATION_MS = 5000; -const isQueryResponseWithoutValue = ( - response: ReturnType>, +const isQueryResponseWithoutValue = ( + response: ReturnType>, ): response is { saveQuery: boolean } => (response as { saveQuery: boolean }).saveQuery != null; /** @@ -88,14 +89,14 @@ const isQueryResponseWithoutValue = ( * 1. The numeric editing when the user presses a digit * 2. The letter editing when the user presses another key */ -export const useFieldCharacterEditing = ({ +export const useFieldCharacterEditing = ({ sections, updateSectionValue, sectionsValueBoundaries, localizedDigits, setTempAndroidValueStr, timezone, -}: UseFieldCharacterEditingParams): UseFieldCharacterEditingResponse => { +}: UseFieldCharacterEditingParams): UseFieldCharacterEditingResponse => { const utils = useUtils(); const [query, setQuery] = React.useState(null); @@ -122,7 +123,7 @@ export const useFieldCharacterEditing = ({ const applyQuery = ( { keyPressed, sectionIndex }: ApplyCharacterEditingParams, - getFirstSectionValueMatchingWithQuery: QueryApplier, + getFirstSectionValueMatchingWithQuery: QueryApplier, isValidQueryValue?: (queryValue: string) => boolean, ): ReturnType => { const cleanKeyPressed = keyPressed.toLowerCase(); @@ -175,7 +176,7 @@ export const useFieldCharacterEditing = ({ format: string, options: string[], queryValue: string, - ): ReturnType> => { + ): ReturnType> => { const matchingValues = options.filter((option) => option.toLowerCase().startsWith(queryValue), ); @@ -192,7 +193,7 @@ export const useFieldCharacterEditing = ({ const testQueryOnFormatAndFallbackFormat = ( queryValue: string, - activeSection: InferFieldSection, + activeSection: InferFieldSection, fallbackFormat?: string, formatFallbackValue?: (fallbackValue: string, fallbackOptions: string[]) => string, ) => { @@ -230,7 +231,7 @@ export const useFieldCharacterEditing = ({ return { saveQuery: false }; }; - const getFirstSectionValueMatchingWithQuery: QueryApplier = ( + const getFirstSectionValueMatchingWithQuery: QueryApplier = ( queryValue, activeSection, ) => { @@ -289,7 +290,7 @@ export const useFieldCharacterEditing = ({ | 'hasLeadingZerosInInput' | 'maxLength' >, - ): ReturnType> => { + ): ReturnType> => { const cleanQueryValue = removeLocalizedDigits(queryValue, localizedDigits); const queryValueNumber = Number(cleanQueryValue); const sectionBoundaries = sectionsValueBoundaries[section.type]({ @@ -324,7 +325,7 @@ export const useFieldCharacterEditing = ({ return { sectionValue: newSectionValue, shouldGoToNextSection }; }; - const getFirstSectionValueMatchingWithQuery: QueryApplier = ( + const getFirstSectionValueMatchingWithQuery: QueryApplier = ( queryValue, activeSection, ) => { 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 b5f4f410ad9a0..1626c95da3e1c 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts @@ -33,13 +33,13 @@ import { GetDefaultReferenceDateProps, getSectionTypeGranularity, } from '../../utils/getDefaultReferenceDate'; -import { InferPickerValue } from '../../models'; +import { PickerValidValue } from '../../models'; -export interface UpdateSectionValueParams { +export interface UpdateSectionValueParams { /** * The section on which we want to apply the new value. */ - activeSection: InferFieldSection; + activeSection: InferFieldSection; /** * Value to apply to the active section. */ @@ -50,38 +50,38 @@ export interface UpdateSectionValueParams { shouldGoToNextSection: boolean; } -export interface UseFieldStateResponse { - state: UseFieldState; +export interface UseFieldStateResponse { + state: UseFieldState; activeSectionIndex: number | null; parsedSelectedSections: FieldParsedSelectedSections; setSelectedSections: (sections: FieldSelectedSections) => void; clearValue: () => void; clearActiveSection: () => void; - updateSectionValue: (params: UpdateSectionValueParams) => void; + updateSectionValue: (params: UpdateSectionValueParams) => void; updateValueFromValueStr: (valueStr: string) => void; setTempAndroidValueStr: (tempAndroidValueStr: string | null) => void; sectionsValueBoundaries: FieldSectionsValueBoundaries; getSectionsFromValue: ( - value: InferPickerValue, - fallbackSections?: InferFieldSection[] | null, - ) => InferFieldSection[]; + value: TValue, + fallbackSections?: InferFieldSection[] | null, + ) => InferFieldSection[]; localizedDigits: string[]; timezone: PickersTimezone; } export const useFieldState = < - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TForwardedProps extends UseFieldForwardedProps, - TInternalProps extends UseFieldInternalProps, + TInternalProps extends UseFieldInternalProps, >( params: UseFieldParams< - TIsRange, + TValue, TEnableAccessibleFieldDOMStructure, TForwardedProps, TInternalProps >, -): UseFieldStateResponse => { +): UseFieldStateResponse => { const utils = useUtils(); const translations = usePickerTranslations(); const adapter = useLocalizationContext(); @@ -128,10 +128,7 @@ export const useFieldState = < ); const getSectionsFromValue = React.useCallback( - ( - value: InferPickerValue, - fallbackSections: InferFieldSection[] | null = null, - ) => + (value: TValue, fallbackSections: InferFieldSection[] | null = null) => fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, (date) => buildSectionsFromFormat({ utils, @@ -158,11 +155,11 @@ export const useFieldState = < ], ); - const [state, setState] = React.useState>(() => { + const [state, setState] = React.useState>(() => { const sections = getSectionsFromValue(valueFromTheOutside); validateSections(sections, valueType); - const stateWithoutReferenceDate: Omit, 'referenceValue'> = { + const stateWithoutReferenceDate: Omit, 'referenceValue'> = { sections, value: valueFromTheOutside, tempValueStrAndroid: null, @@ -207,7 +204,7 @@ export const useFieldState = < value, referenceValue, sections, - }: Pick, 'value' | 'referenceValue' | 'sections'>) => { + }: Pick, 'value' | 'referenceValue' | 'sections'>) => { setState((prevState) => ({ ...prevState, sections, @@ -313,7 +310,7 @@ export const useFieldState = < activeSection, newSectionValue, shouldGoToNextSection, - }: UpdateSectionValueParams) => { + }: UpdateSectionValueParams) => { /** * 1. Decide which section should be focused */ @@ -329,7 +326,7 @@ export const useFieldState = < const newActiveDateSections = activeDateManager.getSections(newSections); const newActiveDate = getDateFromDateSections(utils, newActiveDateSections, localizedDigits); - let values: Pick, 'value' | 'referenceValue'>; + let values: Pick, 'value' | 'referenceValue'>; let shouldPublish: boolean; /** diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts index 5fdf2c07dfed8..719a6561ca6a5 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldV6TextField.ts @@ -6,8 +6,9 @@ import { UseFieldTextFieldInteractions, UseFieldTextField } from './useField.typ import { InferFieldSection } from '../../../models'; import { getActiveElement } from '../../utils/utils'; import { getSectionVisibleValue, isAndroid } from './useField.utils'; +import { PickerValidValue } from '../../models'; -type FieldSectionWithPositions = InferFieldSection & { +type FieldSectionWithPositions = InferFieldSection & { /** * Start index of the section in the format */ @@ -30,14 +31,14 @@ type FieldSectionWithPositions = InferFieldSection dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, ''); -export const addPositionPropertiesToSections = ( - sections: InferFieldSection[], +export const addPositionPropertiesToSections = ( + sections: InferFieldSection[], localizedDigits: string[], isRtl: boolean, -): FieldSectionWithPositions[] => { +): FieldSectionWithPositions[] => { let position = 0; let positionInInput = isRtl ? 1 : 0; - const newSections: FieldSectionWithPositions[] = []; + const newSections: FieldSectionWithPositions[] = []; for (let i = 0; i < sections.length; i += 1) { const section = sections[i]; 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 93dc8f1af11ca..993f245c6c273 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -8,7 +8,7 @@ import { usePicker } from '../usePicker'; import { onSpaceOrEnter } from '../../utils/utils'; import { PickersLayout } from '../../../PickersLayout'; import { FieldRef, InferError } from '../../../models'; -import { BaseSingleInputFieldProps, DateOrTimeViewWithMeridiem } from '../../models'; +import { BaseSingleInputFieldProps, DateOrTimeViewWithMeridiem, PickerValue } from '../../models'; import { PickerProvider } from '../../components/PickerProvider'; /** @@ -50,7 +50,7 @@ export const useMobilePicker = < localeText, } = props; - const fieldRef = React.useRef>(null); + const fieldRef = React.useRef>(null); const labelId = useId(); const isToolbarHidden = innerSlotProps?.toolbar?.hidden ?? false; @@ -63,7 +63,7 @@ export const useMobilePicker = < renderCurrentView, fieldProps: pickerFieldProps, ownerState, - } = usePicker({ + } = usePicker({ ...pickerParams, props, fieldRef, @@ -75,7 +75,7 @@ export const useMobilePicker = < const Field = slots.field; const fieldProps: BaseSingleInputFieldProps< - false, + PickerValue, TEnableAccessibleFieldDOMStructure, InferError > = useSlotProps({ diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts index 6d9fa0bcb9a2e..b4d04f06e66ee 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.types.ts @@ -20,11 +20,11 @@ import { } from '../../../PickersLayout/PickersLayout.types'; import { UsePickerValueNonStaticProps } from '../usePicker/usePickerValue.types'; import { UsePickerViewsNonStaticProps, UsePickerViewsProps } from '../usePicker/usePickerViews'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValue } from '../../models'; export interface UseMobilePickerSlots extends PickersModalDialogSlots, - ExportedPickersLayoutSlots { + ExportedPickersLayoutSlots { /** * Component used to enter the date with the keyboard. */ @@ -40,9 +40,9 @@ export interface ExportedUseMobilePickerSlotProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, > extends PickersModalDialogSlotProps, - ExportedPickersLayoutSlotProps { + ExportedPickersLayoutSlotProps { field?: SlotComponentPropsFromProps< - PickerFieldSlotProps, + PickerFieldSlotProps, {}, PickerOwnerState >; @@ -53,7 +53,7 @@ export interface UseMobilePickerSlotProps< TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, > extends ExportedUseMobilePickerSlotProps, - Pick, 'toolbar'> {} + Pick, 'toolbar'> {} export interface MobileOnlyPickerProps extends BaseNonStaticPickerProps, @@ -66,7 +66,7 @@ export interface UseMobilePickerProps< TEnableAccessibleFieldDOMStructure extends boolean, TError, TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, +> extends BasePickerProps, MakeRequired { /** * Overridable component slots. @@ -90,7 +90,7 @@ export interface UseMobilePickerParams< TExternalProps >, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; 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 08fcf80e1c30e..f6b06d3654562 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -4,14 +4,14 @@ import { usePickerValue } from './usePickerValue'; import { usePickerViews } from './usePickerViews'; import { usePickerLayoutProps } from './usePickerLayoutProps'; import { InferError } from '../../../models'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../../models'; import { usePickerOwnerState } from './usePickerOwnerState'; import { usePickerProvider } from './usePickerProvider'; export const usePicker = < - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerProps, + TExternalProps extends UsePickerProps, TAdditionalProps extends {}, >({ props, @@ -24,8 +24,8 @@ export const usePicker = < rendererInterceptor, fieldRef, localeText, -}: UsePickerParams): UsePickerResponse< - TIsRange, +}: UsePickerParams): UsePickerResponse< + TValue, TView, InferError > => { @@ -38,7 +38,7 @@ export const usePicker = < ]); } } - const pickerValueResponse = usePickerValue({ + const pickerValueResponse = usePickerValue({ props, valueManager, valueType, @@ -46,7 +46,7 @@ export const usePicker = < validator, }); - const pickerViewsResponse = usePickerViews({ + const pickerViewsResponse = usePickerViews({ props, additionalViewProps, autoFocusView, diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts index 807204616ed34..c1886c2300b60 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.types.ts @@ -12,56 +12,56 @@ import { } from './usePickerViews'; import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps'; import { PickerOwnerState } from '../../../models'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../../models'; import { UsePickerProviderParameters, UsePickerProviderReturnValue } from './usePickerProvider'; /** * Props common to all picker headless implementations. */ export interface UsePickerBaseProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, -> extends UsePickerValueBaseProps, - UsePickerViewsBaseProps, +> extends UsePickerValueBaseProps, + UsePickerViewsBaseProps, UsePickerLayoutProps {} export interface UsePickerProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, -> extends UsePickerValueProps, - UsePickerViewsProps, +> extends UsePickerValueProps, + UsePickerViewsProps, UsePickerLayoutProps {} export interface UsePickerParams< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerProps, + TExternalProps extends UsePickerProps, TAdditionalProps extends {}, > extends Pick< - UsePickerValueParams, + UsePickerValueParams, 'valueManager' | 'valueType' | 'wrapperVariant' | 'validator' >, Pick< - UsePickerViewParams, + UsePickerViewParams, 'additionalViewProps' | 'autoFocusView' | 'rendererInterceptor' | 'fieldRef' >, - Pick, 'localeText'> { + Pick, 'localeText'> { props: TExternalProps; } export interface UsePickerResponse< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, -> extends Omit, 'viewProps' | 'layoutProps'>, +> extends Omit, 'viewProps' | 'layoutProps'>, Omit, 'layoutProps'>, - UsePickerLayoutPropsResponse { + UsePickerLayoutPropsResponse { ownerState: PickerOwnerState; providerProps: UsePickerProviderReturnValue; } diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts index 1daec2db78f4c..2c9bb1f17f5bd 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerLayoutProps.ts @@ -3,7 +3,7 @@ import { useIsLandscape } from '../useIsLandscape'; import { UsePickerValueLayoutResponse } from './usePickerValue.types'; import { UsePickerViewsLayoutResponse } from './usePickerViews'; import { DateOrTimeViewWithMeridiem, WrapperVariant } from '../../models/common'; -import { FormProps, InferPickerValue } from '../../models'; +import { FormProps, PickerValidValue } from '../../models'; /** * Props used to create the layout of the views. @@ -17,30 +17,30 @@ export interface UsePickerLayoutProps extends FormProps { } export interface UsePickerLayoutPropsResponseLayoutProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends UsePickerValueLayoutResponse, +> extends UsePickerValueLayoutResponse, UsePickerViewsLayoutResponse, UsePickerLayoutProps { isLandscape: boolean; isRtl: boolean; wrapperVariant: WrapperVariant; - isValid: (value: InferPickerValue) => boolean; + isValid: (value: TValue) => boolean; } export interface UsePickerLayoutPropsResponse< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > { - layoutProps: UsePickerLayoutPropsResponseLayoutProps; + layoutProps: UsePickerLayoutPropsResponseLayoutProps; } export interface UsePickerLayoutPropsParams< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > { props: UsePickerLayoutProps; - propsFromPickerValue: UsePickerValueLayoutResponse; + propsFromPickerValue: UsePickerValueLayoutResponse; propsFromPickerViews: UsePickerViewsLayoutResponse; wrapperVariant: WrapperVariant; } @@ -49,19 +49,19 @@ export interface UsePickerLayoutPropsParams< * Prepare the props for the view layout (managed by `PickersLayout`) */ export const usePickerLayoutProps = < - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, >({ props, propsFromPickerValue, propsFromPickerViews, wrapperVariant, -}: UsePickerLayoutPropsParams): UsePickerLayoutPropsResponse => { +}: UsePickerLayoutPropsParams): UsePickerLayoutPropsResponse => { const { orientation } = props; const isLandscape = useIsLandscape(propsFromPickerViews.views, orientation); const isRtl = useRtl(); - const layoutProps: UsePickerLayoutPropsResponseLayoutProps = { + const layoutProps: UsePickerLayoutPropsResponseLayoutProps = { ...propsFromPickerViews, ...propsFromPickerValue, isLandscape, diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts index 5014acb9c9999..bb05d474abfc1 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts @@ -3,15 +3,16 @@ import { PickerOwnerState } from '../../../models'; import type { UsePickerProps } from './usePicker.types'; import { PickerValueManager, UsePickerValueResponse } from './usePickerValue.types'; import { useUtils } from '../useUtils'; +import { PickerValidValue } from '../../models'; -interface UsePickerOwnerStateParameters { - props: UsePickerProps; - pickerValueResponse: UsePickerValueResponse; - valueManager: PickerValueManager; +interface UsePickerOwnerStateParameters { + props: UsePickerProps; + pickerValueResponse: UsePickerValueResponse; + valueManager: PickerValueManager; } -export function usePickerOwnerState( - parameters: UsePickerOwnerStateParameters, +export function usePickerOwnerState( + parameters: UsePickerOwnerStateParameters, ): PickerOwnerState { const { props, pickerValueResponse, valueManager } = parameters; diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts index f6361e499e71b..ddd340c01e6d7 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerProvider.ts @@ -6,17 +6,18 @@ import { PickerContextValue, PickerPrivateContextValue, } from '../../components/PickerProvider'; +import { PickerValidValue } from '../../models'; -export interface UsePickerProviderParameters +export interface UsePickerProviderParameters extends Pick { - pickerValueResponse: UsePickerValueResponse; + pickerValueResponse: UsePickerValueResponse; ownerState: PickerOwnerState; } export interface UsePickerProviderReturnValue extends Omit {} -export function usePickerProvider( - parameters: UsePickerProviderParameters, +export function usePickerProvider( + parameters: UsePickerProviderParameters, ): UsePickerProviderReturnValue { const { pickerValueResponse, ownerState, localeText } = parameters; 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 0853a147a7e31..167c7854c241c 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -23,14 +23,14 @@ import { PickerValueUpdaterParams, } from './usePickerValue.types'; import { useValueWithTimezone } from '../useValueWithTimezone'; -import { InferPickerValue } from '../../models'; +import { PickerValidValue } from '../../models'; /** * Decide if the new value should be published * The published value will be passed to `onChange` if defined. */ -const shouldPublishValue = ( - params: PickerValueUpdaterParams, +const shouldPublishValue = ( + params: PickerValueUpdaterParams, ): boolean => { const { action, hasChanged, dateState, isControlled } = params; @@ -82,8 +82,8 @@ const shouldPublishValue = ( * The committed value will be passed to `onAccept` if defined. * It will also be used as a reset target when calling the `cancel` picker action (when clicking on the "Cancel" button). */ -const shouldCommitValue = ( - params: PickerValueUpdaterParams, +const shouldCommitValue = ( + params: PickerValueUpdaterParams, ): boolean => { const { action, hasChanged, dateState, isControlled, closeOnSelect } = params; @@ -122,8 +122,8 @@ const shouldCommitValue = ( /** * Decide if the picker should be closed after the value is updated. */ -const shouldClosePicker = ( - params: PickerValueUpdaterParams, +const shouldClosePicker = ( + params: PickerValueUpdaterParams, ): boolean => { const { action, closeOnSelect } = params; @@ -146,16 +146,16 @@ const shouldClosePicker = ( * Manage the value lifecycle of all the pickers. */ export const usePickerValue = < - TIsRange extends boolean, - TExternalProps extends UsePickerValueProps, + TValue extends PickerValidValue, + TExternalProps extends UsePickerValueProps, >({ props, valueManager, valueType, wrapperVariant, validator, -}: UsePickerValueParams): UsePickerValueResponse< - TIsRange, +}: UsePickerValueParams): UsePickerValueResponse< + TValue, InferError > => { type TError = InferError; @@ -220,8 +220,8 @@ export const usePickerValue = < valueManager, }); - const [dateState, setDateState] = React.useState>(() => { - let initialValue: InferPickerValue; + const [dateState, setDateState] = React.useState>(() => { + let initialValue: TValue; if (inValueWithTimezoneToRender !== undefined) { initialValue = inValueWithTimezoneToRender; } else if (defaultValue !== undefined) { @@ -247,8 +247,8 @@ export const usePickerValue = < onError: props.onError, }); - const updateDate = useEventCallback((action: PickerValueUpdateAction) => { - const updaterParams: PickerValueUpdaterParams = { + const updateDate = useEventCallback((action: PickerValueUpdateAction) => { + const updaterParams: PickerValueUpdaterParams = { action, dateState, hasChanged: (comparison) => !valueManager.areValuesEqual(utils, action.value, comparison), @@ -381,13 +381,13 @@ export const usePickerValue = < }); const handleChange = useEventCallback( - (newValue: InferPickerValue, selectionState: PickerSelectionState = 'partial') => + (newValue: TValue, selectionState: PickerSelectionState = 'partial') => updateDate({ name: 'setValueFromView', value: newValue, selectionState }), ); const handleSelectShortcut = useEventCallback( ( - newValue: InferPickerValue, + newValue: TValue, changeImportance: PickerShortcutChangeImportance, shortcut: PickersShortcutsItemContext, ) => @@ -400,7 +400,7 @@ export const usePickerValue = < ); const handleChangeFromField = useEventCallback( - (newValue: InferPickerValue, context: FieldChangeHandlerContext) => + (newValue: TValue, context: FieldChangeHandlerContext) => updateDate({ name: 'setValueFromField', value: newValue, context }), ); @@ -414,7 +414,7 @@ export const usePickerValue = < onClose: handleClose, }; - const fieldResponse: UsePickerValueFieldResponse = { + const fieldResponse: UsePickerValueFieldResponse = { value: dateState.draft, onChange: handleChangeFromField, }; @@ -424,14 +424,14 @@ export const usePickerValue = < [utils, valueManager, dateState.draft], ); - const viewResponse: UsePickerValueViewsResponse = { + const viewResponse: UsePickerValueViewsResponse = { value: viewValue, onChange: handleChange, onClose: handleClose, open: isOpen, }; - const isValid = (testedValue: InferPickerValue) => { + const isValid = (testedValue: TValue) => { const error = validator({ adapter, value: testedValue, @@ -442,7 +442,7 @@ export const usePickerValue = < return !valueManager.hasError(error); }; - const layoutResponse: UsePickerValueLayoutResponse = { + const layoutResponse: UsePickerValueLayoutResponse = { ...actions, value: viewValue, onChange: handleChange, 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 be160a27c2e6c..864e50dd887ea 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 @@ -16,85 +16,74 @@ import { PickerShortcutChangeImportance, PickersShortcutsItemContext, } from '../../../PickersShortcuts'; -import { InferNonNullablePickerValue, InferPickerValue } from '../../models'; +import { InferNonNullablePickerValue, PickerValidValue } from '../../models'; -export interface PickerValueManager { +export interface PickerValueManager { /** * Determines if two values are equal. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The adapter. - * @param {InferPickerValue} valueLeft The first value to compare. - * @param {InferPickerValue} valueRight The second value to compare. + * @param {TValue} valueLeft The first value to compare. + * @param {TValue} valueRight The second value to compare. * @returns {boolean} A boolean indicating if the two values are equal. */ - areValuesEqual: ( - utils: MuiPickersAdapter, - valueLeft: InferPickerValue, - valueRight: InferPickerValue, - ) => boolean; + areValuesEqual: (utils: MuiPickersAdapter, valueLeft: TValue, valueRight: TValue) => boolean; /** * Value to set when clicking the "Clear" button. */ - emptyValue: InferPickerValue; + emptyValue: TValue; /** * Method returning the value to set when clicking the "Today" button - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The adapter. * @param {PickersTimezone} timezone The current timezone. * @param {PickerValueType} valueType The type of the value being edited. - * @returns {InferPickerValue} The value to set when clicking the "Today" button. + * @returns {TValue} The value to set when clicking the "Today" button. */ getTodayValue: ( utils: MuiPickersAdapter, timezone: PickersTimezone, valueType: PickerValueType, - ) => InferPickerValue; + ) => TValue; /** - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * Method returning the reference value to use when mounting the component. * @param {object} params The params of the method. * @param {PickerValidDate | undefined} params.referenceDate The referenceDate provided by the user. - * @param {InferPickerValue} params.value The value provided by the user. + * @param {TValue} params.value The value provided by the user. * @param {GetDefaultReferenceDateProps} params.props The validation props needed to compute the reference value. * @param {MuiPickersAdapter} params.utils The adapter. * @param {number} params.granularity The granularity of the selection possible on this component. * @param {PickersTimezone} params.timezone The current timezone. * @param {() => PickerValidDate} params.getTodayDate The reference date to use if no reference date is passed to the component. - * @returns {InferPickerValue} The reference value to use for non-provided dates. + * @returns {TValue} The reference value to use for non-provided dates. */ getInitialReferenceValue: (params: { referenceDate: PickerValidDate | undefined; - value: InferPickerValue; + value: TValue; props: GetDefaultReferenceDateProps; utils: MuiPickersAdapter; granularity: number; timezone: PickersTimezone; getTodayDate?: () => PickerValidDate; - }) => InferNonNullablePickerValue; + }) => InferNonNullablePickerValue; /** * Method parsing the input value to replace all invalid dates by `null`. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The adapter. - * @param {InferPickerValue} value The value to parse. - * @returns {InferPickerValue} The value without invalid date. + * @param {TValue} value The value to parse. + * @returns {TValue} The value without invalid date. */ - cleanValue: ( - utils: MuiPickersAdapter, - value: InferPickerValue, - ) => InferPickerValue; + cleanValue: (utils: MuiPickersAdapter, value: TValue) => TValue; /** * Generates the new value, given the previous value and the new proposed value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {MuiPickersAdapter} utils The adapter. - * @param {InferPickerValue} lastValidDateValue The last valid value. - * @param {InferPickerValue} value The proposed value. - * @returns {InferPickerValue} The new value. + * @param {TValue} lastValidDateValue The last valid value. + * @param {TValue} value The proposed value. + * @returns {TValue} The new value. */ - valueReducer?: ( - utils: MuiPickersAdapter, - lastValidDateValue: InferPickerValue, - value: InferPickerValue, - ) => InferPickerValue; + valueReducer?: (utils: MuiPickersAdapter, lastValidDateValue: TValue, value: TValue) => TValue; /** * Compare two errors to know if they are equal. * @template TError @@ -117,50 +106,46 @@ export interface PickerValueManager { /** * Return the timezone of the date inside a value. * Throw an error on range picker if both values don't have the same timezone. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. @param {MuiPickersAdapter} utils The utils to manipulate the date. - @param {InferPickerValue} value The current value. + @param {TValue} value The current value. @returns {string | null} The timezone of the current value. */ - getTimezone: (utils: MuiPickersAdapter, value: InferPickerValue) => string | null; + getTimezone: (utils: MuiPickersAdapter, value: TValue) => string | null; /** * Change the timezone of the dates inside a value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. @param {MuiPickersAdapter} utils The utils to manipulate the date. @param {PickersTimezone} timezone The current timezone. - @param {InferPickerValue} value The value to convert. - @returns {InferPickerValue} The value with the new dates in the new timezone. + @param {TValue} value The value to convert. + @returns {TValue} The value with the new dates in the new timezone. */ - setTimezone: ( - utils: MuiPickersAdapter, - timezone: PickersTimezone, - value: InferPickerValue, - ) => InferPickerValue; + setTimezone: (utils: MuiPickersAdapter, timezone: PickersTimezone, value: TValue) => TValue; } export type PickerSelectionState = 'partial' | 'shallow' | 'finish'; -export interface UsePickerValueState { +export interface UsePickerValueState { /** * Date displayed on the views and the field. * It is updated whenever the user modifies something. */ - draft: InferPickerValue; + draft: TValue; /** * Last value published (e.g: the last value for which `shouldPublishValue` returned `true`). * If `onChange` is defined, it's the value that was passed on the last call to this callback. */ - lastPublishedValue: InferPickerValue; + lastPublishedValue: TValue; /** * Last value committed (e.g: the last value for which `shouldCommitValue` returned `true`). * If `onAccept` is defined, it's the value that was passed on the last call to this callback. */ - lastCommittedValue: InferPickerValue; + lastCommittedValue: TValue; /** * Last value passed with `props.value`. * Used to update the `draft` value whenever the `value` prop changes. */ - lastControlledValue: InferPickerValue | undefined; + lastControlledValue: TValue | undefined; /** * If we never modified the value since the mount of the component, * Then we might want to apply some custom logic. @@ -171,39 +156,39 @@ export interface UsePickerValueState { hasBeenModifiedSinceMount: boolean; } -export interface PickerValueUpdaterParams { - action: PickerValueUpdateAction; - dateState: UsePickerValueState; +export interface PickerValueUpdaterParams { + action: PickerValueUpdateAction; + dateState: UsePickerValueState; /** * Check if the new draft value has changed compared to some given value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. - * @param {InferPickerValue} comparisonValue The value to compare the new draft value with. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. + * @param {TValue} comparisonValue The value to compare the new draft value with. * @returns {boolean} `true` if the new draft value is equal to the comparison value. */ - hasChanged: (comparisonValue: InferPickerValue) => boolean; + hasChanged: (comparisonValue: TValue) => boolean; isControlled: boolean; closeOnSelect: boolean; } -export type PickerValueUpdateAction = +export type PickerValueUpdateAction = | { name: 'setValueFromView'; - value: InferPickerValue; + value: TValue; selectionState: PickerSelectionState; } | { name: 'setValueFromField'; - value: InferPickerValue; + value: TValue; context: FieldChangeHandlerContext; } | { name: 'setValueFromAction'; - value: InferPickerValue; + value: TValue; pickerAction: 'accept' | 'today' | 'cancel' | 'dismiss' | 'clear'; } | { name: 'setValueFromShortcut'; - value: InferPickerValue; + value: TValue; changeImportance: PickerShortcutChangeImportance; shortcut: PickersShortcutsItemContext; }; @@ -211,40 +196,34 @@ export type PickerValueUpdateAction = /** * Props used to handle the value that are common to all pickers. */ -export interface UsePickerValueBaseProps - extends OnErrorProps { +export interface UsePickerValueBaseProps + extends OnErrorProps { /** * The selected value. * Used when the component is controlled. */ - value?: InferPickerValue; + value?: TValue; /** * The default value. * Used when the component is not controlled. */ - defaultValue?: InferPickerValue; + defaultValue?: TValue; /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ - onChange?: ( - value: InferPickerValue, - context: PickerChangeHandlerContext, - ) => void; + onChange?: (value: TValue, context: PickerChangeHandlerContext) => void; /** * Callback fired when the value is accepted. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {InferPickerValue} value The value that was just accepted. + * @param {TValue} value The value that was just accepted. * @param {FieldChangeHandlerContext} context The context containing the validation result of the current value. */ - onAccept?: ( - value: InferPickerValue, - context: PickerChangeHandlerContext, - ) => void; + onAccept?: (value: TValue, context: PickerChangeHandlerContext) => void; } /** @@ -276,20 +255,20 @@ export interface UsePickerValueNonStaticProps { /** * Props used to handle the value of the pickers. */ -export interface UsePickerValueProps - extends UsePickerValueBaseProps, +export interface UsePickerValueProps + extends UsePickerValueBaseProps, UsePickerValueNonStaticProps, TimezoneProps {} export interface UsePickerValueParams< - TIsRange extends boolean, - TExternalProps extends UsePickerValueProps, + TValue extends PickerValidValue, + TExternalProps extends UsePickerValueProps, > { props: TExternalProps; - valueManager: PickerValueManager>; + valueManager: PickerValueManager>; valueType: PickerValueType; wrapperVariant: WrapperVariant; - validator: Validator, TExternalProps>; + validator: Validator, TExternalProps>; } export interface UsePickerValueActions { @@ -302,16 +281,16 @@ export interface UsePickerValueActions { onClose: (event?: React.UIEvent) => void; } -export type UsePickerValueFieldResponse = Required< - Pick, 'value' | 'onChange'> +export type UsePickerValueFieldResponse = Required< + Pick, 'value' | 'onChange'> >; /** * Props passed to `usePickerViews`. */ -export interface UsePickerValueViewsResponse { - value: InferPickerValue; - onChange: (value: InferPickerValue, selectionState?: PickerSelectionState) => void; +export interface UsePickerValueViewsResponse { + value: TValue; + onChange: (value: TValue, selectionState?: PickerSelectionState) => void; open: boolean; onClose: (event?: React.MouseEvent) => void; } @@ -319,22 +298,22 @@ export interface UsePickerValueViewsResponse { /** * Props passed to `usePickerLayoutProps`. */ -export interface UsePickerValueLayoutResponse +export interface UsePickerValueLayoutResponse extends UsePickerValueActions { - value: InferPickerValue; - onChange: (newValue: InferPickerValue) => void; + value: TValue; + onChange: (newValue: TValue) => void; onSelectShortcut: ( - newValue: InferPickerValue, + newValue: TValue, changeImportance: PickerShortcutChangeImportance, shortcut: PickersShortcutsItemContext, ) => void; - isValid: (value: InferPickerValue) => boolean; + isValid: (value: TValue) => boolean; } -export interface UsePickerValueResponse { +export interface UsePickerValueResponse { open: boolean; actions: UsePickerValueActions; - viewProps: UsePickerValueViewsResponse; - fieldProps: UsePickerValueFieldResponse; - layoutProps: UsePickerValueLayoutResponse; + viewProps: UsePickerValueViewsResponse; + fieldProps: UsePickerValueFieldResponse; + layoutProps: UsePickerValueLayoutResponse; } diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts index 036c66e279574..599dc21017fcc 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerViews.ts @@ -6,20 +6,25 @@ import useEventCallback from '@mui/utils/useEventCallback'; import { useViews, UseViewsOptions } from '../useViews'; import type { UsePickerValueViewsResponse } from './usePickerValue.types'; import { isTimeView } from '../../utils/time-utils'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { + DateOrTimeViewWithMeridiem, + PickerRangeValue, + PickerValidValue, + PickerValue, +} from '../../models'; import { FieldRef, PickerValidDate, TimezoneProps } from '../../../models'; interface PickerViewsRendererBaseExternalProps extends Omit, 'openTo' | 'viewRenderers'> {} export type PickerViewsRendererProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends PickerViewsRendererBaseExternalProps, TAdditionalProps extends {}, > = Omit & TAdditionalProps & - UsePickerValueViewsResponse & { + UsePickerValueViewsResponse & { view: TView; views: readonly TView[]; focusedView: TView | null; @@ -29,30 +34,30 @@ export type PickerViewsRendererProps< }; export type PickerViewRenderer< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends PickerViewsRendererBaseExternalProps, TAdditionalProps extends {}, > = ( - props: PickerViewsRendererProps, + props: PickerViewsRendererProps, ) => React.ReactNode; export type PickerViewRendererLookup< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TExternalProps extends PickerViewsRendererBaseExternalProps, TAdditionalProps extends {}, > = { - [K in TView]: PickerViewRenderer | null; + [K in TView]: PickerViewRenderer | null; }; /** * Props used to handle the views that are common to all pickers. */ export interface UsePickerViewsBaseProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, > extends Omit, 'onChange' | 'onFocusedViewChange' | 'focusedView'>, TimezoneProps { @@ -60,7 +65,7 @@ export interface UsePickerViewsBaseProps< * If `null`, the section will only have field editing. * If `undefined`, internally defined view will be used. */ - viewRenderers: PickerViewRendererLookup; + viewRenderers: PickerViewRendererLookup; /** * If `true`, disable heavy animations. * @default `@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13 @@ -88,38 +93,38 @@ export interface UsePickerViewsNonStaticProps { * Props used to handle the value of the pickers. */ export interface UsePickerViewsProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, -> extends UsePickerViewsBaseProps { +> extends UsePickerViewsBaseProps { className?: string; sx?: SxProps; } export interface UsePickerViewParams< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, > { props: TExternalProps; - propsFromPickerValue: UsePickerValueViewsResponse; + propsFromPickerValue: UsePickerValueViewsResponse; additionalViewProps: TAdditionalProps; autoFocusView: boolean; - fieldRef: React.RefObject> | undefined; + fieldRef: React.RefObject | FieldRef> | undefined; /** * A function that intercepts the regular picker rendering. * Can be used to consume the provided `viewRenderers` and render a custom component wrapping them. - * @param {PickerViewRendererLookup} viewRenderers The `viewRenderers` that were provided to the picker component. + * @param {PickerViewRendererLookup} viewRenderers The `viewRenderers` that were provided to the picker component. * @param {TView} popperView The current picker view. * @param {any} rendererProps All the props that are being passed down to the renderer. * @returns {React.ReactNode} A React node that will be rendered instead of the default renderer. */ rendererInterceptor?: ( - viewRenderers: PickerViewRendererLookup, + viewRenderers: PickerViewRendererLookup, popperView: TView, - rendererProps: PickerViewsRendererProps, + rendererProps: PickerViewsRendererProps, ) => React.ReactNode; } @@ -146,9 +151,9 @@ export interface UsePickerViewsLayoutResponse, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, >({ props, @@ -158,7 +163,7 @@ export const usePickerViews = < rendererInterceptor, fieldRef, }: UsePickerViewParams< - TIsRange, + TValue, TView, TExternalProps, TAdditionalProps @@ -282,7 +287,7 @@ export const usePickerViews = < } const rendererProps: PickerViewsRendererProps< - TIsRange, + TValue, TView, TExternalProps, TAdditionalProps diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx index 2da95885a89d4..2444ecb61a97d 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.tsx @@ -6,7 +6,7 @@ import { usePicker } from '../usePicker'; import { PickerProvider } from '../../components/PickerProvider'; import { PickersLayout } from '../../../PickersLayout'; import { DIALOG_WIDTH } from '../../constants/dimensions'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValue } from '../../models'; const PickerStaticLayout = styled(PickersLayout)(({ theme }) => ({ overflow: 'hidden', @@ -31,7 +31,7 @@ export const useStaticPicker = < const { localeText, slots, slotProps, className, sx, displayStaticWrapperAs, autoFocus } = props; const { layoutProps, providerProps, renderCurrentView } = usePicker< - false, + PickerValue, TView, TExternalProps, {} diff --git a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts index a72efbd8592ee..aecb74e3eae81 100644 --- a/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts +++ b/packages/x-date-pickers/src/internals/hooks/useStaticPicker/useStaticPicker.types.ts @@ -6,13 +6,13 @@ import { import { BasePickerProps } from '../../models/props/basePickerProps'; import { UsePickerParams } from '../usePicker'; import { UsePickerViewsProps } from '../usePicker/usePickerViews'; -import { DateOrTimeViewWithMeridiem } from '../../models'; +import { DateOrTimeViewWithMeridiem, PickerValue } from '../../models'; export interface UseStaticPickerSlots - extends ExportedPickersLayoutSlots {} + extends ExportedPickersLayoutSlots {} export interface UseStaticPickerSlotProps - extends ExportedPickersLayoutSlotProps {} + extends ExportedPickersLayoutSlotProps {} export interface StaticOnlyPickerProps { /** @@ -36,8 +36,8 @@ export interface StaticOnlyPickerProps { export interface UseStaticPickerProps< TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, -> extends BasePickerProps, + TExternalProps extends UsePickerViewsProps, +> extends BasePickerProps, StaticOnlyPickerProps { /** * Overridable component slots. @@ -55,7 +55,7 @@ export interface UseStaticPickerParams< TView extends DateOrTimeViewWithMeridiem, TExternalProps extends UseStaticPickerProps, > extends Pick< - UsePickerParams, + UsePickerParams, 'valueManager' | 'valueType' | 'validator' > { props: TExternalProps; diff --git a/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts b/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts index a0ef4482a46f2..7b2f09a9f64ae 100644 --- a/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts +++ b/packages/x-date-pickers/src/internals/hooks/useValueWithTimezone.ts @@ -4,7 +4,7 @@ import useControlled from '@mui/utils/useControlled'; import { useUtils } from './useUtils'; import type { PickerValueManager } from './usePicker'; import { PickersTimezone } from '../../models'; -import { InferPickerValue } from '../models'; +import { PickerValidValue } from '../models'; /** * Hooks making sure that: @@ -12,7 +12,7 @@ import { InferPickerValue } from '../models'; * - The value rendered is always the one from `props.timezone` if defined */ export const useValueWithTimezone = < - TIsRange extends boolean, + TValue extends PickerValidValue, TChange extends (...params: any[]) => void, >({ timezone: timezoneProp, @@ -22,10 +22,10 @@ export const useValueWithTimezone = < valueManager, }: { timezone: PickersTimezone | undefined; - value: InferPickerValue | undefined; - defaultValue: InferPickerValue | undefined; + value: TValue | undefined; + defaultValue: TValue | undefined; onChange: TChange | undefined; - valueManager: PickerValueManager; + valueManager: PickerValueManager; }) => { const utils = useUtils(); @@ -37,7 +37,7 @@ export const useValueWithTimezone = < [utils, valueManager, inputValue], ); - const setInputTimezone = useEventCallback((newValue: InferPickerValue) => { + const setInputTimezone = useEventCallback((newValue: TValue) => { if (inputTimezone == null) { return newValue; } @@ -52,12 +52,10 @@ export const useValueWithTimezone = < [valueManager, utils, timezoneToRender, inputValue], ); - const handleValueChange = useEventCallback( - (newValue: InferPickerValue, ...otherParams: any[]) => { - const newValueWithInputTimezone = setInputTimezone(newValue); - onChange?.(newValueWithInputTimezone, ...otherParams); - }, - ) as TChange; + const handleValueChange = useEventCallback((newValue: TValue, ...otherParams: any[]) => { + const newValueWithInputTimezone = setInputTimezone(newValue); + onChange?.(newValueWithInputTimezone, ...otherParams); + }) as TChange; return { value: valueWithTimezoneToRender, handleValueChange, timezone: timezoneToRender }; }; @@ -66,7 +64,7 @@ export const useValueWithTimezone = < * Wrapper around `useControlled` and `useValueWithTimezone` */ export const useControlledValueWithTimezone = < - TIsRange extends boolean, + TValue extends PickerValidValue, TChange extends (...params: any[]) => void, >({ name, @@ -78,10 +76,10 @@ export const useControlledValueWithTimezone = < }: { name: string; timezone: PickersTimezone | undefined; - value: InferPickerValue | undefined; - defaultValue: InferPickerValue | undefined; + value: TValue | undefined; + defaultValue: TValue | undefined; onChange: TChange | undefined; - valueManager: PickerValueManager; + valueManager: PickerValueManager; }) => { const [valueWithInputTimezone, setValue] = useControlled({ name, @@ -90,12 +88,10 @@ export const useControlledValueWithTimezone = < default: defaultValue ?? valueManager.emptyValue, }); - const onChange = useEventCallback( - (newValue: InferPickerValue, ...otherParams: any[]) => { - setValue(newValue); - onChangeProp?.(newValue, ...otherParams); - }, - ) as TChange; + const onChange = useEventCallback((newValue: TValue, ...otherParams: any[]) => { + setValue(newValue); + onChangeProp?.(newValue, ...otherParams); + }) as TChange; return useValueWithTimezone({ timezone: timezoneProp, diff --git a/packages/x-date-pickers/src/internals/hooks/useViews.tsx b/packages/x-date-pickers/src/internals/hooks/useViews.tsx index a493cc36553c4..b26dc412b36c5 100644 --- a/packages/x-date-pickers/src/internals/hooks/useViews.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useViews.tsx @@ -3,7 +3,7 @@ import useEventCallback from '@mui/utils/useEventCallback'; import useControlled from '@mui/utils/useControlled'; import { MakeOptional } from '@mui/x-internals/types'; import type { PickerSelectionState } from './usePicker'; -import { DateOrTimeViewWithMeridiem, InferPickerValue } from '../models'; +import { DateOrTimeViewWithMeridiem, PickerValidValue } from '../models'; import { PickerValidDate } from '../../models'; export type PickerOnChangeFn = ( @@ -12,22 +12,18 @@ export type PickerOnChangeFn = ( ) => void; export interface UseViewsOptions< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > { /** * Callback fired when the value changes. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TView The view type. Will be one of date or time views. - * @param {InferPickerValue} value The new value. + * @param {TValue} value The new value. * @param {PickerSelectionState | undefined} selectionState Indicates if the date selection is complete. * @param {TView | undefined} selectedView Indicates the view in which the selection has been made. */ - onChange: ( - value: InferPickerValue, - selectionState?: PickerSelectionState, - selectedView?: TView, - ) => void; + onChange: (value: TValue, selectionState?: PickerSelectionState, selectedView?: TView) => void; /** * Callback fired on view change. * @template TView @@ -71,13 +67,16 @@ export interface UseViewsOptions< } export interface ExportedUseViewsOptions< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, -> extends MakeOptional, 'onChange' | 'openTo' | 'views'> {} +> extends MakeOptional, 'onChange' | 'openTo' | 'views'> {} let warnedOnceNotValidView = false; -interface UseViewsResponse { +interface UseViewsResponse< + TValue extends PickerValidValue, + TView extends DateOrTimeViewWithMeridiem, +> { view: TView; setView: (view: TView) => void; focusedView: TView | null; @@ -87,13 +86,16 @@ interface UseViewsResponse void; setValueAndGoToNextView: ( - value: InferPickerValue, + value: TValue, currentViewSelectionState?: PickerSelectionState, selectedView?: TView, ) => void; } -export function useViews({ +export function useViews< + TValue extends PickerValidValue, + TView extends DateOrTimeViewWithMeridiem, +>({ onChange, onViewChange, openTo, @@ -102,7 +104,7 @@ export function useViews): UseViewsResponse { +}: UseViewsOptions): UseViewsResponse { if (process.env.NODE_ENV !== 'production') { if (!warnedOnceNotValidView) { if (inView != null && !views.includes(inView)) { @@ -191,11 +193,7 @@ export function useViews, - currentViewSelectionState?: PickerSelectionState, - selectedView?: TView, - ) => { + (value: TValue, currentViewSelectionState?: PickerSelectionState, selectedView?: TView) => { const isSelectionFinishedOnCurrentView = currentViewSelectionState === 'finish'; const hasMoreViews = selectedView ? // handles case like `DateTimePicker`, where a view might return a `finish` selection state diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index 0c45e50833b93..f1d7fb1465aea 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -122,10 +122,11 @@ export type { DateTimeValidationProps, } from './models/validation'; export type { + PickerValue, PickerRangeValue, PickerNonNullableRangeValue, - InferPickerValue, InferNonNullablePickerValue, + PickerValidValue, } from './models/value'; export { convertFieldResponseIntoMuiTextFieldProps } from './utils/convertFieldResponseIntoMuiTextFieldProps'; diff --git a/packages/x-date-pickers/src/internals/models/fields.ts b/packages/x-date-pickers/src/internals/models/fields.ts index ffb08bbc77661..b7476ca12f049 100644 --- a/packages/x-date-pickers/src/internals/models/fields.ts +++ b/packages/x-date-pickers/src/internals/models/fields.ts @@ -8,6 +8,7 @@ import type { import type { FieldSection, PickerOwnerState } from '../../models'; import type { UseFieldInternalProps } from '../hooks/useField'; import { RangePosition } from './pickers'; +import { PickerValidValue } from './value'; export interface FieldRangeSection extends FieldSection { dateName: RangePosition; @@ -44,12 +45,12 @@ export interface BaseForwardedSingleInputFieldProps extends ExportedUseClearable * Only contains what the MUI components are passing to the field, not what users can pass using the `props.slotProps.field`. */ export type BaseSingleInputFieldProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, TError, > = MakeRequired< Pick< - UseFieldInternalProps, + UseFieldInternalProps, | 'readOnly' | 'disabled' | 'format' diff --git a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx index 1a72e6c59ba2a..c4fef0bdaa157 100644 --- a/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx +++ b/packages/x-date-pickers/src/internals/models/props/basePickerProps.tsx @@ -7,17 +7,18 @@ import { PickersInputComponentLocaleText } from '../../../locales/utils/pickersL import type { UsePickerViewsProps } from '../../hooks/usePicker/usePickerViews'; import { DateOrTimeViewWithMeridiem } from '../common'; import { UseFieldInternalProps } from '../../hooks/useField'; +import { PickerValidValue } from '../value'; /** * Props common to all pickers after applying the default props on each picker. */ export interface BasePickerProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, - TExternalProps extends UsePickerViewsProps, + TExternalProps extends UsePickerViewsProps, TAdditionalProps extends {}, -> extends UsePickerBaseProps { +> extends UsePickerBaseProps { className?: string; /** * The system prop that allows defining system overrides as well as additional CSS styles. @@ -34,11 +35,11 @@ export interface BasePickerProps< * Props common to all pickers before applying the default props on each picker. */ export interface BasePickerInputProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, TError, > extends Omit< - MakeOptional, 'openTo' | 'views'>, + MakeOptional, 'openTo' | 'views'>, 'viewRenderers' > {} diff --git a/packages/x-date-pickers/src/internals/models/props/time.ts b/packages/x-date-pickers/src/internals/models/props/time.ts index 6a055a0ba22e7..81583861b148d 100644 --- a/packages/x-date-pickers/src/internals/models/props/time.ts +++ b/packages/x-date-pickers/src/internals/models/props/time.ts @@ -6,6 +6,7 @@ import type { ExportedUseViewsOptions } from '../../hooks/useViews'; import { TimeViewWithMeridiem } from '../common'; import { ExportedValidateTimeProps } from '../../../validation/validateTime'; import { FormProps } from '../formProps'; +import { PickerValue } from '../value'; export interface AmPmProps { /** @@ -21,7 +22,7 @@ export interface ExportedBaseClockProps AmPmProps {} export interface BaseClockProps - extends ExportedUseViewsOptions, + extends ExportedUseViewsOptions, ExportedBaseClockProps, FormProps { className?: string; diff --git a/packages/x-date-pickers/src/internals/models/props/toolbar.ts b/packages/x-date-pickers/src/internals/models/props/toolbar.ts index ab81380528976..b1c70623cc723 100644 --- a/packages/x-date-pickers/src/internals/models/props/toolbar.ts +++ b/packages/x-date-pickers/src/internals/models/props/toolbar.ts @@ -3,16 +3,16 @@ import { SxProps } from '@mui/system'; import { Theme } from '@mui/material/styles'; import { DateOrTimeViewWithMeridiem } from '../common'; import { FormProps } from '../formProps'; -import { InferPickerValue } from '../value'; +import { PickerValidValue } from '../value'; export interface BaseToolbarProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TView extends DateOrTimeViewWithMeridiem, > extends ExportedBaseToolbarProps, FormProps { isLandscape: boolean; - onChange: (newValue: InferPickerValue) => void; - value: InferPickerValue; + onChange: (newValue: TValue) => void; + value: TValue; /** * Currently visible picker view. */ diff --git a/packages/x-date-pickers/src/internals/models/value.ts b/packages/x-date-pickers/src/internals/models/value.ts index 371c126d3c76f..8f70fe9eb4ad8 100644 --- a/packages/x-date-pickers/src/internals/models/value.ts +++ b/packages/x-date-pickers/src/internals/models/value.ts @@ -6,14 +6,11 @@ export type PickerRangeValue = [PickerValidDate | null, PickerValidDate | null]; export type PickerNonNullableRangeValue = [PickerValidDate, PickerValidDate]; -export type InferPickerValue = TIsRange extends true - ? TIsRange extends false - ? PickerValue | PickerRangeValue - : PickerRangeValue - : PickerValue; +export type PickerValidValue = PickerValue | PickerRangeValue; -export type InferNonNullablePickerValue = TIsRange extends true - ? TIsRange extends false - ? PickerValidDate | PickerNonNullableRangeValue - : PickerNonNullableRangeValue - : PickerValidDate; +export type InferNonNullablePickerValue = + TValue extends PickerRangeValue + ? TValue extends PickerValue + ? PickerValidDate | PickerNonNullableRangeValue + : PickerNonNullableRangeValue + : PickerValidDate; diff --git a/packages/x-date-pickers/src/internals/utils/valueManagers.ts b/packages/x-date-pickers/src/internals/utils/valueManagers.ts index 5c476694b18af..ae9a8d91ad703 100644 --- a/packages/x-date-pickers/src/internals/utils/valueManagers.ts +++ b/packages/x-date-pickers/src/internals/utils/valueManagers.ts @@ -7,10 +7,11 @@ import { createDateStrForV7HiddenInputFromSections, createDateStrForV6InputFromSections, } from '../hooks/useField/useField.utils'; +import { PickerValue } from '../models'; export type SingleItemPickerValueManager< TError extends DateValidationError | TimeValidationError | DateTimeValidationError = any, -> = PickerValueManager; +> = PickerValueManager; export const singleItemValueManager: SingleItemPickerValueManager = { emptyValue: null, @@ -37,7 +38,7 @@ export const singleItemValueManager: SingleItemPickerValueManager = { value == null ? null : utils.setTimezone(value, timezone), }; -export const singleItemFieldValueManager: FieldValueManager = { +export const singleItemFieldValueManager: FieldValueManager = { updateReferenceValue: (utils, value, prevReferenceValue) => value == null || !utils.isValid(value) ? prevReferenceValue : value, getSectionsFromValue: (utils, date, prevSections, getSectionsFromDate) => { diff --git a/packages/x-date-pickers/src/models/fields.ts b/packages/x-date-pickers/src/models/fields.ts index 6e2972c327b5c..55f14ebdce1ac 100644 --- a/packages/x-date-pickers/src/models/fields.ts +++ b/packages/x-date-pickers/src/models/fields.ts @@ -7,7 +7,12 @@ import type { import { ExportedPickersSectionListProps } from '../PickersSectionList'; import type { UseFieldInternalProps, UseFieldResponse } from '../internals/hooks/useField'; import type { PickersTextFieldProps } from '../PickersTextField'; -import { BaseForwardedSingleInputFieldProps, FieldRangeSection } from '../internals/models'; +import { + BaseForwardedSingleInputFieldProps, + FieldRangeSection, + PickerRangeValue, + PickerValidValue, +} from '../internals/models'; // Update PickersComponentAgnosticLocaleText -> viewNames when adding new entries export type FieldSectionType = @@ -86,18 +91,22 @@ export interface FieldSection { endSeparator: string; } -export type InferFieldSection = TIsRange extends true - ? TIsRange extends false - ? FieldSection | FieldRangeSection - : FieldRangeSection - : FieldSection; +// If `PickerValidDate` contains `any`, then `TValue extends PickerRangeValue` will return true, so we have to handle this edge case first. +type IsAny = boolean extends (T extends never ? true : false) ? true : false; -export interface FieldRef { +export type InferFieldSection = + IsAny extends true + ? FieldSection + : TValue extends PickerRangeValue + ? FieldRangeSection + : FieldSection; + +export interface FieldRef { /** * Returns the sections of the current value. - * @returns {InferFieldSection[]} The sections of the current value. + * @returns {InferFieldSection[]} The sections of the current value. */ - getSections: () => InferFieldSection[]; + getSections: () => InferFieldSection[]; /** * Returns the index of the active section (the first focused section). * If no section is active, returns `null`. @@ -127,11 +136,11 @@ export type FieldSelectedSections = number | FieldSectionType | null | 'all'; * Props the prop `slotProps.field` of a picker can receive. */ export type PickerFieldSlotProps< - TIsRange extends boolean, + TValue extends PickerValidValue, TEnableAccessibleFieldDOMStructure extends boolean, > = ExportedUseClearableFieldProps & Pick< - UseFieldInternalProps, + UseFieldInternalProps, 'shouldRespectLeadingZeros' | 'readOnly' > & React.HTMLAttributes & { diff --git a/packages/x-date-pickers/src/models/validation.ts b/packages/x-date-pickers/src/models/validation.ts index 735751aec51a4..affbfcdcb259b 100644 --- a/packages/x-date-pickers/src/models/validation.ts +++ b/packages/x-date-pickers/src/models/validation.ts @@ -1,4 +1,4 @@ -import type { InferPickerValue } from '../internals/models'; +import type { PickerValidValue } from '../internals/models'; /** * Validation error types applicable to both date and time validation @@ -24,17 +24,17 @@ export type TimeValidationError = export type DateTimeValidationError = DateValidationError | TimeValidationError; -export interface OnErrorProps { +export interface OnErrorProps { /** * Callback fired when the error associated with 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. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @param {TError} error The reason why the current value is not valid. - * @param {InferPickerValue} value The value associated with the error. + * @param {TValue} value The value associated with the error. */ - onError?: (error: TError, value: InferPickerValue) => void; + onError?: (error: TError, value: TValue) => void; } export type InferError = TProps extends { onError?: (error: any, value: any) => void } diff --git a/packages/x-date-pickers/src/themeAugmentation/props.d.ts b/packages/x-date-pickers/src/themeAugmentation/props.d.ts index 19c3066219df2..f5bdfe45dadea 100644 --- a/packages/x-date-pickers/src/themeAugmentation/props.d.ts +++ b/packages/x-date-pickers/src/themeAugmentation/props.d.ts @@ -52,6 +52,7 @@ import { PickersFilledInputProps, } from '../PickersTextField'; import { PickersSectionListProps } from '../PickersSectionList'; +import { PickerValidValue } from '../internals/models'; export interface PickersComponentsPropsList { MuiClock: ClockProps; @@ -77,10 +78,10 @@ export interface PickersComponentsPropsList { MuiPickersMonth: ExportedPickersMonthProps; MuiPickersPopper: PickerPopperProps; MuiPickersSlideTransition: ExportedSlideTransitionProps; - MuiPickersToolbar: PickersToolbarProps; + MuiPickersToolbar: PickersToolbarProps; MuiPickersToolbarButton: PickersToolbarButtonProps; MuiPickersToolbarText: ExportedPickersToolbarTextProps; - MuiPickersLayout: PickersLayoutProps; + MuiPickersLayout: PickersLayoutProps; MuiPickersYear: ExportedPickersYearProps; MuiTimeClock: TimeClockProps; MuiTimeField: TimeFieldProps; diff --git a/packages/x-date-pickers/src/validation/useValidation.ts b/packages/x-date-pickers/src/validation/useValidation.ts index 598b7af37787f..f9708c1f63632 100644 --- a/packages/x-date-pickers/src/validation/useValidation.ts +++ b/packages/x-date-pickers/src/validation/useValidation.ts @@ -5,24 +5,24 @@ import { useLocalizationContext } from '../internals/hooks/useUtils'; import { MuiPickersAdapterContextValue } from '../LocalizationProvider/LocalizationProvider'; import { OnErrorProps, PickersTimezone } from '../models'; import type { PickerValueManager } from '../internals/hooks/usePicker'; -import { InferPickerValue } from '../internals/models'; +import { PickerValidValue } from '../internals/models'; -export type Validator = { +export type Validator = { (params: { adapter: MuiPickersAdapterContextValue; - value: InferPickerValue; + value: TValue; timezone: PickersTimezone; props: TValidationProps; }): TError; - valueManager: PickerValueManager; + valueManager: PickerValueManager; }; -interface UseValidationOptions - extends OnErrorProps { +interface UseValidationOptions + extends OnErrorProps { /** * The value to validate. */ - value: InferPickerValue; + value: TValue; /** * The timezone to use for the validation. */ @@ -33,7 +33,7 @@ interface UseValidationOptions; + validator: Validator; /** * The validation props, they differ depending on the component. * For example, the `validateTime` function supports `minTime`, `maxTime`, etc. @@ -41,7 +41,7 @@ interface UseValidationOptions { +interface UseValidationReturnValue { /** * The validation error associated to the value passed to the `useValidation` hook. */ @@ -55,27 +55,27 @@ interface UseValidationReturnValue { /** * 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 TIsRange `true` if the value comes from a range picker, `false` otherwise. - * @param {InferPickerValue} newValue The value to validate. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. + * @param {TValue} newValue The value to validate. * @returns {TError} The validation error associated to the new value. */ - getValidationErrorForNewValue: (newValue: InferPickerValue) => TError; + getValidationErrorForNewValue: (newValue: TValue) => TError; } /** * Utility hook to check if a given value is valid based on the provided validation props. - * @template TIsRange `true` if the value comes from a range picker, `false` otherwise. + * @template TValue The value type. It will be the same type as `value` or `null`. It can be in `[start, end]` format in case of range value. * @template TError The validation error type. It will be either `string` or a `null`. It can be in `[start, end]` format in case of range value. - * @param {UseValidationOptions} options The options to configure the hook. - * @param {InferPickerValue} options.value The value to validate. + * @param {UseValidationOptions} options The options to configure the hook. + * @param {TValue} options.value The value to validate. * @param {PickersTimezone} options.timezone The timezone to use for the validation. - * @param {Validator} options.validator The validator function to use. + * @param {Validator} options.validator The validator function to use. * @param {TValidationProps} options.props The validation props, they differ depending on the component. - * @param {(error: TError, value: InferPickerValue) => void} options.onError Callback fired when the error associated with the current value changes. + * @param {(error: TError, value: TValue) => void} options.onError Callback fired when the error associated with the current value changes. */ -export function useValidation( - options: UseValidationOptions, -): UseValidationReturnValue { +export function useValidation( + options: UseValidationOptions, +): UseValidationReturnValue { const { props, validator, value, timezone, onError } = options; const adapter = useLocalizationContext(); @@ -97,7 +97,7 @@ export function useValidation) => { + const getValidationErrorForNewValue = useEventCallback((newValue: TValue) => { return validator({ adapter, value: newValue, timezone, props }); }); diff --git a/packages/x-date-pickers/src/validation/validateDate.ts b/packages/x-date-pickers/src/validation/validateDate.ts index cf6995363110f..6ee413e372a9f 100644 --- a/packages/x-date-pickers/src/validation/validateDate.ts +++ b/packages/x-date-pickers/src/validation/validateDate.ts @@ -8,6 +8,7 @@ import { import { DateValidationError } from '../models'; import { applyDefaultDate } from '../internals/utils/date-utils'; import { singleItemValueManager } from '../internals/utils/valueManagers'; +import { PickerValue } from '../internals/models'; /** * Validation props used by the Date Picker, Date Field and Date Calendar components. @@ -24,7 +25,7 @@ export interface ValidateDateProps YearValidationProps, Required {} -export const validateDate: Validator = ({ +export const validateDate: Validator = ({ props, value, timezone, diff --git a/packages/x-date-pickers/src/validation/validateDateTime.ts b/packages/x-date-pickers/src/validation/validateDateTime.ts index b827b21c888f8..50f5e8437246b 100644 --- a/packages/x-date-pickers/src/validation/validateDateTime.ts +++ b/packages/x-date-pickers/src/validation/validateDateTime.ts @@ -4,6 +4,7 @@ import { ExportedValidateTimeProps, validateTime, ValidateTimeProps } from './va import { DateTimeValidationError } from '../models'; import { singleItemValueManager } from '../internals/utils/valueManagers'; import { DateTimeValidationProps } from '../internals/models/validation'; +import { PickerValue } from '../internals/models'; /** * Validation props used by the Date Time Picker and Date Time Field components. @@ -15,12 +16,11 @@ export interface ExportedValidateDateTimeProps export interface ValidateDateTimeProps extends ValidateDateProps, ValidateTimeProps {} -export const validateDateTime: Validator = ({ - adapter, - value, - timezone, - props, -}) => { +export const validateDateTime: Validator< + PickerValue, + DateTimeValidationError, + ValidateDateTimeProps +> = ({ adapter, value, timezone, props }) => { const dateValidationResult = validateDate({ adapter, value, diff --git a/packages/x-date-pickers/src/validation/validateTime.ts b/packages/x-date-pickers/src/validation/validateTime.ts index 87e626d7aa671..d28c21149e0e1 100644 --- a/packages/x-date-pickers/src/validation/validateTime.ts +++ b/packages/x-date-pickers/src/validation/validateTime.ts @@ -3,6 +3,7 @@ import { Validator } from './useValidation'; import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation'; import { TimeValidationError } from '../models'; import { singleItemValueManager } from '../internals/utils/valueManagers'; +import { PickerValue } from '../internals/models'; /** * Validation props used by the Time Picker, Time Field and Clock components. @@ -11,7 +12,7 @@ export interface ExportedValidateTimeProps extends BaseTimeValidationProps, Time export interface ValidateTimeProps extends Required, TimeValidationProps {} -export const validateTime: Validator = ({ +export const validateTime: Validator = ({ adapter, value, timezone, diff --git a/test/utils/pickers/describeValue/describeValue.tsx b/test/utils/pickers/describeValue/describeValue.tsx index 4e2e1aed3ab80..7565a92501cfa 100644 --- a/test/utils/pickers/describeValue/describeValue.tsx +++ b/test/utils/pickers/describeValue/describeValue.tsx @@ -1,6 +1,10 @@ import * as React from 'react'; import createDescribe from '@mui/internal-test-utils/createDescribe'; -import { BasePickerInputProps, UsePickerValueNonStaticProps } from '@mui/x-date-pickers/internals'; +import { + BasePickerInputProps, + PickerValidValue, + UsePickerValueNonStaticProps, +} from '@mui/x-date-pickers/internals'; import { buildFieldInteractions, BuildFieldInteractionsResponse } from 'test/utils/pickers'; import { PickerComponentFamily } from '../describe.types'; import { DescribeValueOptions, DescribeValueTestSuite } from './describeValue.types'; @@ -16,15 +20,15 @@ const TEST_SUITES: DescribeValueTestSuite[] = [ testShortcuts, ]; -function innerDescribeValue( +function innerDescribeValue( ElementToTest: React.FunctionComponent, - getOptions: () => DescribeValueOptions, + getOptions: () => DescribeValueOptions, ) { const options = getOptions(); const { defaultProps, render, clock, componentFamily } = options; function WrappedElementToTest( - props: BasePickerInputProps & UsePickerValueNonStaticProps & { hook?: any }, + props: BasePickerInputProps & UsePickerValueNonStaticProps & { hook?: any }, ) { const { hook, ...other } = props; const hookResult = hook?.(props); @@ -68,23 +72,23 @@ function innerDescribeValue { - const typedTestSuite = testSuite as DescribeValueTestSuite; + const typedTestSuite = testSuite as DescribeValueTestSuite; typedTestSuite(WrappedElementToTest, { ...options, renderWithProps }); }); } -type P = [ +type P = [ React.FunctionComponent, - () => DescribeValueOptions, + () => DescribeValueOptions, ]; type DescribeValue = { - (...args: P): void; - skip: ( - ...args: P + (...args: P): void; + skip: ( + ...args: P ) => void; - only: ( - ...args: P + only: ( + ...args: P ) => void; }; diff --git a/test/utils/pickers/describeValue/describeValue.types.ts b/test/utils/pickers/describeValue/describeValue.types.ts index 511a4935eeb3e..c1cb3b358d3fe 100644 --- a/test/utils/pickers/describeValue/describeValue.types.ts +++ b/test/utils/pickers/describeValue/describeValue.types.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import { createRenderer, MuiRenderResult } from '@mui/internal-test-utils/createRenderer'; -import { InferPickerValue, InferNonNullablePickerValue } from '@mui/x-date-pickers/internals'; +import { InferNonNullablePickerValue, PickerValidValue } from '@mui/x-date-pickers/internals'; import { BuildFieldInteractionsResponse, FieldPressCharacter, @@ -9,12 +9,15 @@ import { } from 'test/utils/pickers'; import { PickerComponentFamily } from '../describe.types'; -interface DescribeValueBaseOptions { +interface DescribeValueBaseOptions< + TValue extends PickerValidValue, + C extends PickerComponentFamily, +> { componentFamily: C; render: (node: React.ReactElement) => MuiRenderResult; - assertRenderedValue: (expectedValue: InferPickerValue) => void; - values: [InferNonNullablePickerValue, InferNonNullablePickerValue]; - emptyValue: InferPickerValue; + assertRenderedValue: (expectedValue: TValue) => void; + values: [InferNonNullablePickerValue, InferNonNullablePickerValue]; + emptyValue: TValue; defaultProps?: object; // TODO: Export `Clock` from monorepo clock: ReturnType['clock']; @@ -22,12 +25,12 @@ interface DescribeValueBaseOptions = DescribeValueBaseOptions & + TValue extends PickerValidValue, +> = DescribeValueBaseOptions & (C extends 'picker' ? OpenPickerParams & { setNewValue: ( - value: InferNonNullablePickerValue, + value: InferNonNullablePickerValue, options: { selectSection: FieldSectionSelector; pressKey: FieldPressCharacter; @@ -35,18 +38,21 @@ export type DescribeValueOptions< applySameValue?: boolean; setEndDate?: boolean; }, - ) => InferNonNullablePickerValue; + ) => InferNonNullablePickerValue; } : { setNewValue: ( - value: InferPickerValue, + value: TValue, options: { selectSection: FieldSectionSelector; pressKey: FieldPressCharacter }, - ) => InferPickerValue; + ) => TValue; }); -export type DescribeValueTestSuite = ( +export type DescribeValueTestSuite< + TValue extends PickerValidValue, + C extends PickerComponentFamily, +> = ( ElementToTest: React.FunctionComponent, - options: DescribeValueOptions & { + options: DescribeValueOptions & { renderWithProps: BuildFieldInteractionsResponse['renderWithProps']; }, ) => void; diff --git a/test/utils/pickers/describeValue/testPickerActionBar.tsx b/test/utils/pickers/describeValue/testPickerActionBar.tsx index 6bf1a2eadf205..7497f806866c1 100644 --- a/test/utils/pickers/describeValue/testPickerActionBar.tsx +++ b/test/utils/pickers/describeValue/testPickerActionBar.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import { fireEvent, screen } from '@mui/internal-test-utils'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerRangeValue } from '@mui/x-date-pickers/internals'; import { adapterToUse, getExpectedOnChangeCount, @@ -107,7 +107,7 @@ export const testPickerActionBar: DescribeValueTestSuite = ( getExpectedOnChangeCount(componentFamily, pickerParams) + 1, ); if (isRangeType) { - (values[0] as DateRange).forEach((value, index) => { + (values[0] as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { diff --git a/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx b/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx index c114367e9a20b..8a5601814ce2f 100644 --- a/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx +++ b/test/utils/pickers/describeValue/testPickerOpenCloseLifeCycle.tsx @@ -2,12 +2,12 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import { fireEvent, screen } from '@mui/internal-test-utils'; -import { DateRange } from '@mui/x-date-pickers-pro/models'; +import { PickerRangeValue, PickerValidValue } from '@mui/x-date-pickers/internals'; import { getExpectedOnChangeCount, getFieldInputRoot, openPicker } from 'test/utils/pickers'; import { DescribeValueTestSuite } from './describeValue.types'; import { fireUserEvent } from '../../fireUserEvent'; -export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite = ( +export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite = ( ElementToTest, options, ) => { @@ -79,7 +79,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite).forEach((value, index) => { + (newValue as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { @@ -137,7 +137,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite).forEach((value, index) => { + (newValue as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { @@ -213,7 +213,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite).forEach((value, index) => { + (newValue as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { @@ -236,7 +236,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite).forEach((value, index) => { + (newValueBis as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { @@ -278,7 +278,7 @@ export const testPickerOpenCloseLifeCycle: DescribeValueTestSuite).forEach((value, index) => { + (newValue as PickerRangeValue).forEach((value, index) => { expect(onChange.lastCall.args[0][index]).toEqualDateTime(value); }); } else { diff --git a/test/utils/pickers/fields.tsx b/test/utils/pickers/fields.tsx index ce2878952e41e..052d39f1e032a 100644 --- a/test/utils/pickers/fields.tsx +++ b/test/utils/pickers/fields.tsx @@ -5,6 +5,7 @@ import { createRenderer, screen, act, fireEvent } from '@mui/internal-test-utils import { FieldRef, FieldSectionType } from '@mui/x-date-pickers/models'; import { pickersSectionListClasses } from '@mui/x-date-pickers/PickersSectionList'; import { pickersInputBaseClasses } from '@mui/x-date-pickers/PickersTextField'; +import { PickerValue } from '@mui/x-date-pickers/internals'; import { fireUserEvent } from '../fireUserEvent'; import { expectFieldValueV7, expectFieldValueV6 } from './assertions'; @@ -88,10 +89,10 @@ export const buildFieldInteractions =

({ props, { hook, componentFamily = 'field', direction = 'ltr' } = {}, ) => { - let fieldRef: React.RefObject> = { current: null }; + let fieldRef: React.RefObject> = { current: null }; function WrappedComponent(propsFromRender: any) { - fieldRef = React.useRef>(null); + fieldRef = React.useRef>(null); const hookResult = hook?.(propsFromRender); const allProps = {