Skip to content

Commit

Permalink
[pickers] Create the new picker's ownerState object (#14889)
Browse files Browse the repository at this point in the history
  • Loading branch information
flaviendelangle authored Oct 16, 2024
1 parent 19d2255 commit a005076
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -81,6 +80,7 @@ export const useDesktopPicker = <
shouldRestoreFocus,
fieldProps: pickerFieldProps,
contextValue,
ownerState,
} = usePicker<TDate | null, TDate, TView, FieldSection, TExternalProps, {}>({
...pickerParams,
props,
Expand All @@ -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,
Expand Down Expand Up @@ -122,7 +117,7 @@ export const useDesktopPicker = <
const openPickerIconProps = useSlotProps({
elementType: OpenPickerIcon,
externalSlotProps: innerSlotProps?.openPickerIcon,
ownerState: ownerStateV8,
ownerState,
});

const Field = slots.field;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -66,10 +71,6 @@ export interface UseDesktopPickerSlotProps<
> extends ExportedUseDesktopPickerSlotProps<TDate, TView, TEnableAccessibleFieldDOMStructure>,
Pick<PickersLayoutSlotProps<TDate | null, TDate, TView>, 'toolbar'> {}

export interface UseDesktopPickerOwnerState {
open: boolean;
}

export interface ExportedUseDesktopPickerSlotProps<
TDate extends PickerValidDate,
TView extends DateOrTimeViewWithMeridiem,
Expand All @@ -95,7 +96,11 @@ export interface ExportedUseDesktopPickerSlotProps<
{},
UseDesktopPickerProps<TDate, any, TEnableAccessibleFieldDOMStructure, any, any>
>;
openPickerIcon?: SlotComponentPropsFromProps<Record<string, any>, {}, UseDesktopPickerOwnerState>;
openPickerIcon?: SlotComponentPropsFromProps<
Record<string, any>,
{},
PickerOwnerState<TDate | null>
>;
}

export interface DesktopOnlyPickerProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -71,6 +72,8 @@ export const usePicker = <
propsFromPickerViews: pickerViewsResponse.layoutProps,
});

const pickerOwnerState = usePickerOwnerState({ props, pickerValueResponse });

return {
// Picker value
open: pickerValueResponse.open,
Expand All @@ -87,5 +90,8 @@ export const usePicker = <

// Picker context
contextValue: pickerValueResponse.contextValue,

// Picker owner state
ownerState: pickerOwnerState,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -64,4 +64,6 @@ export interface UsePickerResponse<
TError,
> extends Omit<UsePickerValueResponse<TValue, TSection, TError>, 'viewProps' | 'layoutProps'>,
Omit<UsePickerViewsResponse<TView>, 'layoutProps'>,
UsePickerLayoutPropsResponse<TValue, TView> {}
UsePickerLayoutPropsResponse<TValue, TView> {
ownerState: PickerOwnerState<TValue>;
}
Original file line number Diff line number Diff line change
@@ -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<TValue> {
props: UsePickerProps<TValue, any, any, any, any, any>;
pickerValueResponse: UsePickerValueResponse<TValue, FieldSection, any>;
}

export function usePickerOwnerState<TValue>(
parameters: UsePickerOwnerStateParameters<TValue>,
): PickerOwnerState<TValue> {
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],
);
}
19 changes: 19 additions & 0 deletions packages/x-date-pickers/src/models/pickers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,22 @@ export interface PickerValidDateLookup {}
export type PickerValidDate = keyof PickerValidDateLookup extends never
? any
: PickerValidDateLookup[keyof PickerValidDateLookup];

export interface PickerOwnerState<TValue> {
/**
* 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;
}
1 change: 1 addition & 0 deletions scripts/x-date-pickers-pro.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down
1 change: 1 addition & 0 deletions scripts/x-date-pickers.exports.json
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down

0 comments on commit a005076

Please sign in to comment.