Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pickers] Create the new picker's ownerState object #14889

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be in favor of keeping the object as minimal as possible for now and add more properties as user request them.

But if you have another property that you think is important, I can of course add it 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently manually add WrapperVariant to use in some slots like the ActionBar and ToolBar. Perhaps it will be cleaner to add it directly to the hook instead ? 
I see it as an information that can be valuable for customization in any slot.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a very good candidate for the ownerState indeed 👌

I propose to treat it in a follow up, because I'm not sure we want to have it in its current shape.
We discussed following MD3 nomenclature (docked and modal) instead of mobile and desktop and this would impact the name of this property.

/**
* 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