Skip to content

Commit

Permalink
[pickers] Introduce a new concept of manager (mui#15339)
Browse files Browse the repository at this point in the history
Signed-off-by: Flavien DELANGLE <[email protected]>
Co-authored-by: Lukas Tyla <[email protected]>
  • Loading branch information
flaviendelangle and LukasTy authored Dec 31, 2024
1 parent e5471d4 commit 20e037b
Show file tree
Hide file tree
Showing 29 changed files with 905 additions and 263 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
'use client';
import * as React from 'react';
import { useField, useDefaultizedDateField, PickerRangeValue } from '@mui/x-date-pickers/internals';
import {
useField,
useFieldInternalPropsWithDefaults,
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';
import { validateDateRange } from '../validation';
import { useDateRangeManager } from '../managers';

export const useSingleInputDateRangeField = <
TEnableAccessibleFieldDOMStructure extends boolean,
TAllProps extends UseSingleInputDateRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
>(
inProps: TAllProps,
props: TAllProps,
) => {
const props = useDefaultizedDateField<
UseSingleInputDateRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
TAllProps
>(inProps);

const manager = useDateRangeManager(props);
const { forwardedProps, internalProps } = useSplitFieldProps(props, 'date');

const fieldValueManager = React.useMemo(
() => getRangeFieldValueManager({ dateSeparator: internalProps.dateSeparator }),
[internalProps.dateSeparator],
);
const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
manager,
internalProps,
});

return useField<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
typeof forwardedProps,
typeof internalProps
typeof internalPropsWithDefaults
>({
forwardedProps,
internalProps,
valueManager: rangeValueManager,
fieldValueManager,
validator: validateDateRange,
valueType: 'date',
internalProps: internalPropsWithDefaults,
valueManager: manager.internal_valueManager,
fieldValueManager: manager.internal_fieldValueManager,
validator: manager.validator,
valueType: manager.valueType,
});
};
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
'use client';
import * as React from 'react';
import {
useField,
useDefaultizedDateTimeField,
useFieldInternalPropsWithDefaults,
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';
import { validateDateTimeRange } from '../validation';
import { useDateTimeRangeManager } from '../managers';

export const useSingleInputDateTimeRangeField = <
TEnableAccessibleFieldDOMStructure extends boolean,
TAllProps extends UseSingleInputDateTimeRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
>(
inProps: TAllProps,
props: TAllProps,
) => {
const props = useDefaultizedDateTimeField<
UseSingleInputDateTimeRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
TAllProps
>(inProps);

const manager = useDateTimeRangeManager(props);
const { forwardedProps, internalProps } = useSplitFieldProps(props, 'date-time');

const fieldValueManager = React.useMemo(
() => getRangeFieldValueManager({ dateSeparator: internalProps.dateSeparator }),
[internalProps.dateSeparator],
);
const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
manager,
internalProps,
});

return useField<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
typeof forwardedProps,
typeof internalProps
typeof internalPropsWithDefaults
>({
forwardedProps,
internalProps,
valueManager: rangeValueManager,
fieldValueManager,
validator: validateDateTimeRange,
valueType: 'date-time',
internalProps: internalPropsWithDefaults,
valueManager: manager.internal_valueManager,
fieldValueManager: manager.internal_fieldValueManager,
validator: manager.validator,
valueType: manager.valueType,
});
};
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
'use client';
import * as React from 'react';
import { useField, useDefaultizedTimeField, PickerRangeValue } from '@mui/x-date-pickers/internals';
import {
useField,
useFieldInternalPropsWithDefaults,
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';
import { validateTimeRange } from '../validation';
import { useTimeRangeManager } from '../managers';

export const useSingleInputTimeRangeField = <
TEnableAccessibleFieldDOMStructure extends boolean,
TAllProps extends UseSingleInputTimeRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
>(
inProps: TAllProps,
props: TAllProps,
) => {
const props = useDefaultizedTimeField<
UseSingleInputTimeRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
TAllProps
>(inProps);

const manager = useTimeRangeManager(props);
const { forwardedProps, internalProps } = useSplitFieldProps(props, 'time');

const fieldValueManager = React.useMemo(
() => getRangeFieldValueManager({ dateSeparator: internalProps.dateSeparator }),
[internalProps.dateSeparator],
);
const internalPropsWithDefaults = useFieldInternalPropsWithDefaults({
manager,
internalProps,
});

return useField<
PickerRangeValue,
TEnableAccessibleFieldDOMStructure,
typeof forwardedProps,
typeof internalProps
typeof internalPropsWithDefaults
>({
forwardedProps,
internalProps,
valueManager: rangeValueManager,
fieldValueManager,
validator: validateTimeRange,
valueType: 'time',
internalProps: internalPropsWithDefaults,
valueManager: manager.internal_valueManager,
fieldValueManager: manager.internal_fieldValueManager,
validator: manager.validator,
valueType: manager.valueType,
});
};
1 change: 1 addition & 0 deletions packages/x-date-pickers-pro/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ export * from './dateRangeViewRenderers';
export * from './models';
export * from './hooks';
export * from './validation';
export * from './managers';
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,24 @@ import {
PickerValue,
UseFieldResponse,
useControlledValueWithTimezone,
useDefaultizedDateField,
useFieldInternalPropsWithDefaults,
} from '@mui/x-date-pickers/internals';
import { useValidation } from '@mui/x-date-pickers/validation';
import { DateValidationError } from '@mui/x-date-pickers/models';
import {
UseMultiInputDateRangeFieldParams,
UseMultiInputDateRangeFieldProps,
} from '../../../MultiInputDateRangeField/MultiInputDateRangeField.types';
import { UseMultiInputDateRangeFieldParams } from '../../../MultiInputDateRangeField/MultiInputDateRangeField.types';
import { validateDateRange } from '../../../validation';
import { rangeValueManager } from '../../utils/valueManagers';
import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
import { DateRangeValidationError } from '../../../models';
import { excludeProps } from './shared';
import { useMultiInputFieldSelectedSections } from '../useMultiInputFieldSelectedSections';
import { useDateRangeManager } from '../../../managers';

export const useMultiInputDateRangeField = <
TEnableAccessibleFieldDOMStructure extends boolean,
TTextFieldSlotProps extends {},
>({
sharedProps: inSharedProps,
sharedProps,
startTextFieldProps,
unstableStartFieldRef,
endTextFieldProps,
Expand All @@ -35,10 +33,11 @@ export const useMultiInputDateRangeField = <
TEnableAccessibleFieldDOMStructure,
TTextFieldSlotProps
>): UseMultiInputRangeFieldResponse<TEnableAccessibleFieldDOMStructure, TTextFieldSlotProps> => {
const sharedProps = useDefaultizedDateField<
UseMultiInputDateRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
typeof inSharedProps
>(inSharedProps);
const manager = useDateRangeManager(sharedProps);
const sharedPropsWithDefaults = useFieldInternalPropsWithDefaults({
manager,
internalProps: sharedProps,
});

const {
value: valueProp,
Expand All @@ -55,7 +54,7 @@ export const useMultiInputDateRangeField = <
timezone: timezoneProp,
enableAccessibleFieldDOMStructure,
autoFocus,
} = sharedProps;
} = sharedPropsWithDefaults;

const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
name: 'useMultiInputDateRangeField',
Expand All @@ -68,11 +67,11 @@ export const useMultiInputDateRangeField = <
});

const { validationError, getValidationErrorForNewValue } = useValidation({
props: sharedProps,
props: sharedPropsWithDefaults,
value,
timezone,
validator: validateDateRange,
onError: sharedProps.onError,
onError: sharedPropsWithDefaults.onError,
});

// TODO: Maybe export utility from `useField` instead of copy/pasting the logic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,24 @@ import {
PickerValue,
UseFieldResponse,
useControlledValueWithTimezone,
useDefaultizedDateTimeField,
useFieldInternalPropsWithDefaults,
} from '@mui/x-date-pickers/internals';
import { DateTimeValidationError } from '@mui/x-date-pickers/models';
import { useValidation } from '@mui/x-date-pickers/validation';
import type {
UseMultiInputDateTimeRangeFieldParams,
UseMultiInputDateTimeRangeFieldProps,
} from '../../../MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types';
import { DateTimeRangeValidationError } from '../../../models';
import { DateTimeValidationError } from '@mui/x-date-pickers/models';
import { UseMultiInputDateTimeRangeFieldParams } from '../../../MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types';
import { validateDateTimeRange } from '../../../validation';
import { rangeValueManager } from '../../utils/valueManagers';
import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
import { DateTimeRangeValidationError } from '../../../models';
import { excludeProps } from './shared';
import { useMultiInputFieldSelectedSections } from '../useMultiInputFieldSelectedSections';
import { useDateTimeRangeManager } from '../../../managers';

export const useMultiInputDateTimeRangeField = <
TEnableAccessibleFieldDOMStructure extends boolean,
TTextFieldSlotProps extends {},
>({
sharedProps: inSharedProps,
sharedProps,
startTextFieldProps,
unstableStartFieldRef,
endTextFieldProps,
Expand All @@ -35,10 +33,11 @@ export const useMultiInputDateTimeRangeField = <
TEnableAccessibleFieldDOMStructure,
TTextFieldSlotProps
>): UseMultiInputRangeFieldResponse<TEnableAccessibleFieldDOMStructure, TTextFieldSlotProps> => {
const sharedProps = useDefaultizedDateTimeField<
UseMultiInputDateTimeRangeFieldProps<TEnableAccessibleFieldDOMStructure>,
typeof inSharedProps
>(inSharedProps);
const manager = useDateTimeRangeManager(sharedProps);
const sharedPropsWithDefaults = useFieldInternalPropsWithDefaults({
manager,
internalProps: sharedProps,
});

const {
value: valueProp,
Expand All @@ -55,10 +54,10 @@ export const useMultiInputDateTimeRangeField = <
timezone: timezoneProp,
enableAccessibleFieldDOMStructure,
autoFocus,
} = sharedProps;
} = sharedPropsWithDefaults;

const { value, handleValueChange, timezone } = useControlledValueWithTimezone({
name: 'useMultiInputDateRangeField',
name: 'useMultiInputDateTimeRangeField',
timezone: timezoneProp,
value: valueProp,
defaultValue,
Expand All @@ -68,11 +67,11 @@ export const useMultiInputDateTimeRangeField = <
});

const { validationError, getValidationErrorForNewValue } = useValidation({
props: sharedProps,
props: sharedPropsWithDefaults,
value,
timezone,
validator: validateDateTimeRange,
onError: sharedProps.onError,
onError: sharedPropsWithDefaults.onError,
});

// TODO: Maybe export utility from `useField` instead of copy/pasting the logic
Expand Down
Loading

0 comments on commit 20e037b

Please sign in to comment.