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 bd77cbc4d0e9..a874ca8cd3f1 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -6,7 +6,6 @@ import useForkRef from '@mui/utils/useForkRef'; import useId from '@mui/utils/useId'; import { PickersPopper } from '../../components/PickersPopper'; import { - UseDesktopPickerOwnerState, UseDesktopPickerParams, UseDesktopPickerProps, UseDesktopPickerSlotProps, @@ -81,6 +80,7 @@ export const useDesktopPicker = < shouldRestoreFocus, fieldProps: pickerFieldProps, contextValue, + ownerState, } = usePicker({ ...pickerParams, props, @@ -90,11 +90,6 @@ export const useDesktopPicker = < wrapperVariant: 'desktop', }); - // TODO v8: Apply this ownerState to all the slots in this hook. - const ownerStateV8: UseDesktopPickerOwnerState = { - open, - }; - const InputAdornment = slots.inputAdornment ?? MuiInputAdornment; const { ownerState: inputAdornmentOwnerState, ...inputAdornmentProps } = useSlotProps({ elementType: InputAdornment, @@ -122,7 +117,7 @@ export const useDesktopPicker = < const openPickerIconProps = useSlotProps({ elementType: OpenPickerIcon, externalSlotProps: innerSlotProps?.openPickerIcon, - ownerState: ownerStateV8, + ownerState, }); const Field = slots.field; 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 494e25e6b25a..5b23cfdb47b0 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 @@ -10,7 +10,12 @@ import { } from '../../models/props/basePickerProps'; import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models'; +import { + BaseSingleInputFieldProps, + FieldSection, + PickerOwnerState, + PickerValidDate, +} from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -66,10 +71,6 @@ export interface UseDesktopPickerSlotProps< > extends ExportedUseDesktopPickerSlotProps, Pick, 'toolbar'> {} -export interface UseDesktopPickerOwnerState { - open: boolean; -} - export interface ExportedUseDesktopPickerSlotProps< TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, @@ -95,7 +96,11 @@ export interface ExportedUseDesktopPickerSlotProps< {}, UseDesktopPickerProps >; - openPickerIcon?: SlotComponentPropsFromProps, {}, UseDesktopPickerOwnerState>; + openPickerIcon?: SlotComponentPropsFromProps< + Record, + {}, + PickerOwnerState + >; } export interface DesktopOnlyPickerProps 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 3d290f0ded8c..45c351390d05 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -5,6 +5,7 @@ import { usePickerViews } from './usePickerViews'; import { usePickerLayoutProps } from './usePickerLayoutProps'; import { FieldSection, PickerValidDate, InferError } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; +import { usePickerOwnerState } from './usePickerOwnerState'; export const usePicker = < TValue, @@ -71,6 +72,8 @@ export const usePicker = < propsFromPickerViews: pickerViewsResponse.layoutProps, }); + const pickerOwnerState = usePickerOwnerState({ props, pickerValueResponse }); + return { // Picker value open: pickerValueResponse.open, @@ -87,5 +90,8 @@ export const usePicker = < // Picker context contextValue: pickerValueResponse.contextValue, + + // Picker owner state + ownerState: pickerOwnerState, }; }; 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 21c6ec9ed51f..5bc23631a90d 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 @@ -11,7 +11,7 @@ import { UsePickerViewsBaseProps, } from './usePickerViews'; import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps'; -import { FieldSection, PickerValidDate } from '../../../models'; +import { FieldSection, PickerOwnerState, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; /** @@ -64,4 +64,6 @@ export interface UsePickerResponse< TError, > extends Omit, 'viewProps' | 'layoutProps'>, Omit, 'layoutProps'>, - UsePickerLayoutPropsResponse {} + UsePickerLayoutPropsResponse { + ownerState: PickerOwnerState; +} diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts new file mode 100644 index 000000000000..07b5fbfccebb --- /dev/null +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerOwnerState.ts @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { FieldSection, PickerOwnerState } from '../../../models'; +import type { UsePickerProps } from './usePicker.types'; +import { UsePickerValueResponse } from './usePickerValue.types'; + +interface UsePickerOwnerStateParameters { + props: UsePickerProps; + pickerValueResponse: UsePickerValueResponse; +} + +export function usePickerOwnerState( + parameters: UsePickerOwnerStateParameters, +): PickerOwnerState { + const { props, pickerValueResponse } = parameters; + + return React.useMemo( + () => ({ + value: pickerValueResponse.viewProps.value, + open: pickerValueResponse.open, + disabled: props.disabled ?? false, + readOnly: props.readOnly ?? false, + }), + [pickerValueResponse.viewProps.value, pickerValueResponse.open, props.disabled, props.readOnly], + ); +} diff --git a/packages/x-date-pickers/src/models/pickers.ts b/packages/x-date-pickers/src/models/pickers.ts index 16e67bd94f2c..c15c2e5d1e71 100644 --- a/packages/x-date-pickers/src/models/pickers.ts +++ b/packages/x-date-pickers/src/models/pickers.ts @@ -14,3 +14,22 @@ export interface PickerValidDateLookup {} export type PickerValidDate = keyof PickerValidDateLookup extends never ? any : PickerValidDateLookup[keyof PickerValidDateLookup]; + +export interface PickerOwnerState { + /** + * The value currently displayed in the field and in the view. + */ + value: TValue; + /** + * `true` if the picker is open, `false` otherwise. + */ + open: boolean; + /** + * `true` if the picker is disabled, `false` otherwise. + */ + disabled: boolean; + /** + * `true` if the picker is read-only, `false` otherwise. + */ + readOnly: boolean; +} diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index c0c3e0d39b25..7bce2723c04e 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -248,6 +248,7 @@ { "name": "NonEmptyDateRange", "kind": "TypeAlias" }, { "name": "OnErrorProps", "kind": "Interface" }, { "name": "PickerChangeHandlerContext", "kind": "Interface" }, + { "name": "PickerOwnerState", "kind": "Interface" }, { "name": "PickersActionBar", "kind": "Function" }, { "name": "PickersActionBarAction", "kind": "TypeAlias" }, { "name": "PickersActionBarProps", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index e432b56a60af..df1cacc6fcfe 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -163,6 +163,7 @@ { "name": "MultiSectionDigitalClockSlots", "kind": "Interface" }, { "name": "OnErrorProps", "kind": "Interface" }, { "name": "PickerChangeHandlerContext", "kind": "Interface" }, + { "name": "PickerOwnerState", "kind": "Interface" }, { "name": "PickersActionBar", "kind": "Function" }, { "name": "PickersActionBarAction", "kind": "TypeAlias" }, { "name": "PickersActionBarProps", "kind": "Interface" },