From ffda3783283eb10e1166940a94de31dd74738fbd Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 09:38:10 +0200 Subject: [PATCH 01/33] [docs] New recipe of a read-only field --- ...ustomBehaviorMaterialTextField.tsx.preview | 5 ++ ...CustomReadonlyBehaviorMaterialTextField.js | 45 +++++++++++++++ ...ustomReadonlyBehaviorMaterialTextField.tsx | 47 ++++++++++++++++ ...donlyBehaviorMaterialTextField.tsx.preview | 1 + .../date-pickers/custom-field/custom-field.md | 4 ++ docs/next-env.d.ts | 2 +- packages/x-date-pickers/src/hooks/index.tsx | 2 + .../src/hooks/useFieldPlaceholder.ts | 55 +++++++++++++++++++ 8 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview create mode 100644 docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js create mode 100644 docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx create mode 100644 docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview create mode 100644 packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts diff --git a/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview new file mode 100644 index 000000000000..173a0ba16962 --- /dev/null +++ b/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview @@ -0,0 +1,5 @@ + setValue(newValue)} +/> \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js new file mode 100644 index 000000000000..f7707e50b9bf --- /dev/null +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js @@ -0,0 +1,45 @@ +import * as React from 'react'; + +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; + +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; +import TextField from '@mui/material/TextField'; + +function ReadonlyField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { InputProps, slotProps, slots, ...other } = forwardedProps; + + const placeholder = useFieldPlaceholder(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + return ( + + ); +} + +function ReadonlyFieldDatePicker(props) { + return ; +} + +export default function CustomReadonlyBehaviorMaterialTextField() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx new file mode 100644 index 000000000000..f978ee151dbf --- /dev/null +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx @@ -0,0 +1,47 @@ +import * as React from 'react'; +import { Dayjs } from 'dayjs'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker, DatePickerProps } from '@mui/x-date-pickers/DatePicker'; +import { DateFieldInPickerProps } from '@mui/x-date-pickers/DateField'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; +import TextField from '@mui/material/TextField'; + +function ReadonlyField(props: DateFieldInPickerProps) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { InputProps, slotProps, slots, ...other } = forwardedProps; + + const placeholder = useFieldPlaceholder(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + return ( + + ); +} + +function ReadonlyFieldDatePicker( + props: Omit, 'open' | 'onOpen' | 'onClose'>, +) { + return ; +} + +export default function CustomReadonlyBehaviorMaterialTextField() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview new file mode 100644 index 000000000000..5442e4084c47 --- /dev/null +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index b58ea51d833f..7c25826b1876 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -151,6 +151,10 @@ Learn more about the accessible DOM structure and its difference compared to the ## Usage with another UI +### Using a read-only `TextField` + +{{"demo": "CustomReadonlyBehaviorMaterialTextField.js", "defaultCodeOpen": false}} + ### Using an `Autocomplete` If your user can only select a value in a small list of available dates, diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts index 4f11a03dc6cc..a4a7b3f5cfa2 100644 --- a/docs/next-env.d.ts +++ b/docs/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. diff --git a/packages/x-date-pickers/src/hooks/index.tsx b/packages/x-date-pickers/src/hooks/index.tsx index e4ca216906f0..c19ca7b21d6e 100644 --- a/packages/x-date-pickers/src/hooks/index.tsx +++ b/packages/x-date-pickers/src/hooks/index.tsx @@ -9,3 +9,5 @@ export type { export { usePickersTranslations } from './usePickersTranslations'; export { useSplitFieldProps } from './useSplitFieldProps'; + +export { useFieldPlaceholder } from './useFieldPlaceholder'; diff --git a/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts b/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts new file mode 100644 index 000000000000..ad5d9a34669b --- /dev/null +++ b/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { useRtl } from '@mui/system/RtlProvider'; +import { useUtils } from '../internals/hooks/useUtils'; +import { buildSectionsFromFormat } from '../internals/hooks/useField/buildSectionsFromFormat'; +import { getLocalizedDigits } from '../internals/hooks/useField/useField.utils'; +import { PickersTimezone, PickerValidDate } from '../models'; +import { usePickersTranslations } from './usePickersTranslations'; + +interface UseFieldPlaceholderParams { + format: string; + formatDensity?: 'dense' | 'spacious'; + timezone: PickersTimezone; + shouldRespectLeadingZeros?: boolean; +} + +export const useFieldPlaceholder = ({ + format, + formatDensity = 'dense', + timezone, + shouldRespectLeadingZeros = false, +}: UseFieldPlaceholderParams) => { + const utils = useUtils(); + const isRtl = useRtl(); + const translations = usePickersTranslations(); + const localizedDigits = React.useMemo(() => getLocalizedDigits(utils), [utils]); + + return React.useMemo(() => { + const sections = buildSectionsFromFormat({ + utils, + format, + formatDensity, + isRtl, + timezone, + shouldRespectLeadingZeros, + localeText: translations, + localizedDigits, + date: null, + // TODO v9: Make sure we still don't reverse in `buildSectionsFromFormat` when using `useFieldPlaceholder`. + enableAccessibleFieldDOMStructure: false, + }); + + return sections + .map((section) => `${section.startSeparator}${section.placeholder}${section.endSeparator}`) + .join(''); + }, [ + utils, + isRtl, + translations, + localizedDigits, + format, + formatDensity, + timezone, + shouldRespectLeadingZeros, + ]); +}; From 81099d236b2fe3a84d3b6b69d7f8c9d8b6047311 Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 09:42:29 +0200 Subject: [PATCH 02/33] Fix --- .../custom-field/CustomBehaviorMaterialTextField.tsx.preview | 5 ----- .../CustomReadonlyBehaviorMaterialTextField.tsx.preview | 1 - docs/next-env.d.ts | 2 +- 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview delete mode 100644 docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview deleted file mode 100644 index 173a0ba16962..000000000000 --- a/docs/data/date-pickers/custom-field/CustomBehaviorMaterialTextField.tsx.preview +++ /dev/null @@ -1,5 +0,0 @@ - setValue(newValue)} -/> \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview deleted file mode 100644 index 5442e4084c47..000000000000 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts index a4a7b3f5cfa2..4f11a03dc6cc 100644 --- a/docs/next-env.d.ts +++ b/docs/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/basic-features/typescript for more information. From 95075ddc3f3114968e0588d77e59e1826f13095e Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 09:44:39 +0200 Subject: [PATCH 03/33] Fix --- .../custom-field/CustomReadonlyBehaviorMaterialTextField.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx index f978ee151dbf..ec8b0f0fef7d 100644 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx @@ -32,9 +32,7 @@ function ReadonlyField(props: DateFieldInPickerProps) { ); } -function ReadonlyFieldDatePicker( - props: Omit, 'open' | 'onOpen' | 'onClose'>, -) { +function ReadonlyFieldDatePicker(props: DatePickerProps) { return ; } From 92da0c7323ea1a04aa115769a42b3dd268af9995 Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 09:49:52 +0200 Subject: [PATCH 04/33] Fix --- .../custom-field/CustomReadonlyBehaviorMaterialTextField.js | 6 ++++-- .../CustomReadonlyBehaviorMaterialTextField.tsx | 6 ++++-- .../CustomReadonlyBehaviorMaterialTextField.tsx.preview | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js index f7707e50b9bf..1ba2af7ffd41 100644 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js @@ -8,7 +8,7 @@ import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; import TextField from '@mui/material/TextField'; -function ReadonlyField(props) { +function ReadonlyDateField(props) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; @@ -33,7 +33,9 @@ function ReadonlyField(props) { } function ReadonlyFieldDatePicker(props) { - return ; + return ( + + ); } export default function CustomReadonlyBehaviorMaterialTextField() { diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx index ec8b0f0fef7d..b0dff280b893 100644 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx @@ -8,7 +8,7 @@ import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; import TextField from '@mui/material/TextField'; -function ReadonlyField(props: DateFieldInPickerProps) { +function ReadonlyDateField(props: DateFieldInPickerProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; @@ -33,7 +33,9 @@ function ReadonlyField(props: DateFieldInPickerProps) { } function ReadonlyFieldDatePicker(props: DatePickerProps) { - return ; + return ( + + ); } export default function CustomReadonlyBehaviorMaterialTextField() { diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview new file mode 100644 index 000000000000..5442e4084c47 --- /dev/null +++ b/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file From b79b5f4fd158adbedb86fb41bfec34e3124577d4 Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 10:06:57 +0200 Subject: [PATCH 05/33] Add onOpen prop --- .../ReadonlyMaterialTextField.js} | 5 +++-- .../ReadonlyMaterialTextField.tsx} | 5 +++-- .../ReadonlyMaterialTextField.tsx.preview} | 0 docs/data/date-pickers/custom-field/custom-field.md | 2 +- packages/x-date-pickers/src/hooks/useSplitFieldProps.ts | 1 + .../internals/hooks/useDesktopPicker/useDesktopPicker.tsx | 1 + packages/x-date-pickers/src/internals/models/fields.ts | 1 + 7 files changed, 10 insertions(+), 5 deletions(-) rename docs/data/date-pickers/custom-field/{CustomReadonlyBehaviorMaterialTextField.js => custom-behavior/ReadonlyMaterialTextField.js} (90%) rename docs/data/date-pickers/custom-field/{CustomReadonlyBehaviorMaterialTextField.tsx => custom-behavior/ReadonlyMaterialTextField.tsx} (91%) rename docs/data/date-pickers/custom-field/{CustomReadonlyBehaviorMaterialTextField.tsx.preview => custom-behavior/ReadonlyMaterialTextField.tsx.preview} (100%) diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js similarity index 90% rename from docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js rename to docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js index 1ba2af7ffd41..9714150e884c 100644 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js @@ -10,7 +10,7 @@ import TextField from '@mui/material/TextField'; function ReadonlyDateField(props) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - const { value, timezone, format } = internalProps; + const { value, timezone, format, onOpen } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; const placeholder = useFieldPlaceholder(internalProps); @@ -28,6 +28,7 @@ function ReadonlyDateField(props) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} + onClick={onOpen} /> ); } @@ -38,7 +39,7 @@ function ReadonlyFieldDatePicker(props) { ); } -export default function CustomReadonlyBehaviorMaterialTextField() { +export default function ReadonlyMaterialTextField() { return ( diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx similarity index 91% rename from docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx rename to docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx index b0dff280b893..e55dc5224358 100644 --- a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx @@ -10,7 +10,7 @@ import TextField from '@mui/material/TextField'; function ReadonlyDateField(props: DateFieldInPickerProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - const { value, timezone, format } = internalProps; + const { value, timezone, format, onOpen } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; const placeholder = useFieldPlaceholder(internalProps); @@ -28,6 +28,7 @@ function ReadonlyDateField(props: DateFieldInPickerProps) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} + onClick={onOpen} /> ); } @@ -38,7 +39,7 @@ function ReadonlyFieldDatePicker(props: DatePickerProps) { ); } -export default function CustomReadonlyBehaviorMaterialTextField() { +export default function ReadonlyMaterialTextField() { return ( diff --git a/docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview similarity index 100% rename from docs/data/date-pickers/custom-field/CustomReadonlyBehaviorMaterialTextField.tsx.preview rename to docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index 7c25826b1876..20ca0d4c7f0c 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -153,7 +153,7 @@ Learn more about the accessible DOM structure and its difference compared to the ### Using a read-only `TextField` -{{"demo": "CustomReadonlyBehaviorMaterialTextField.js", "defaultCodeOpen": false}} +{{"demo": "custom-behavior/ReadonlyMaterialTextField.js", "defaultCodeOpen": false}} ### Using an `Autocomplete` diff --git a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts index 35a29a7bc094..67bbe25e9d12 100644 --- a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts +++ b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts @@ -24,6 +24,7 @@ const SHARED_FIELD_INTERNAL_PROP_NAMES = [ 'disabled', 'readOnly', 'dateSeparator', + 'onOpen', ] as const; type InternalPropNames = 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 b13a78700e27..673a80006898 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -156,6 +156,7 @@ export const useDesktopPicker = < timezone, label, name, + onOpen: actions.onOpen, autoFocus: autoFocus && !props.open, focused: open ? true : undefined, ...(inputRef ? { inputRef } : {}), diff --git a/packages/x-date-pickers/src/internals/models/fields.ts b/packages/x-date-pickers/src/internals/models/fields.ts index e02b43315f56..032622ed41ce 100644 --- a/packages/x-date-pickers/src/internals/models/fields.ts +++ b/packages/x-date-pickers/src/internals/models/fields.ts @@ -18,4 +18,5 @@ export interface BaseFieldProps< format?: string; disabled?: boolean; ref?: React.Ref; + onOpen: (event: React.UIEvent) => void; } From c7a1032ccf4247b07d4983b056d0bf9413ecdd2c Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 10:27:49 +0200 Subject: [PATCH 06/33] Fix types --- .../src/DesktopDatePicker/DesktopDatePicker.tsx | 2 +- .../DesktopDateTimePicker/DesktopDateTimePicker.tsx | 2 +- .../src/DesktopTimePicker/DesktopTimePicker.tsx | 2 +- .../src/MobileDatePicker/MobileDatePicker.tsx | 2 +- .../src/MobileDateTimePicker/MobileDateTimePicker.tsx | 2 +- .../src/MobileTimePicker/MobileTimePicker.tsx | 2 +- .../hooks/useDesktopPicker/useDesktopPicker.types.ts | 8 ++++++-- .../hooks/useMobilePicker/useMobilePicker.tsx | 1 + .../hooks/useMobilePicker/useMobilePicker.types.ts | 8 ++++++-- packages/x-date-pickers/src/models/fields.ts | 11 +++++++++++ 10 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index 5410f886c89b..d0fa8f380466 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -72,7 +72,7 @@ const DesktopDatePicker = React.forwardRef(function DesktopDatePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index d5907a41b083..e767f8489571 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -197,7 +197,7 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 966c729b6365..7ff550001e1f 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -105,7 +105,7 @@ const DesktopTimePicker = React.forwardRef(function DesktopTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 8a8aeefb380e..e2d7824d8bb0 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -69,7 +69,7 @@ const MobileDatePicker = React.forwardRef(function MobileDatePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 1bf3bbb56e20..d52382080431 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -79,7 +79,7 @@ const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index 5898915dfd1b..e49287194d6c 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -72,7 +72,7 @@ const MobileTimePicker = React.forwardRef(function MobileTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), + ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), ...extractValidationProps(defaultizedProps), ref, }), 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..426a2ba4b70d 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,11 @@ import { } from '../../models/props/basePickerProps'; import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models'; +import { + BaseSingleInputFieldPropsInPickerSlots, + FieldSection, + PickerValidDate, +} from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -78,7 +82,7 @@ export interface ExportedUseDesktopPickerSlotProps< ExportedPickersLayoutSlotProps, UseClearableFieldSlotProps { field?: SlotComponentPropsFromProps< - BaseSingleInputFieldProps< + BaseSingleInputFieldPropsInPickerSlots< TDate | null, TDate, FieldSection, 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 6145d21537ae..208fd5721387 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -118,6 +118,7 @@ export const useMobilePicker = < timezone, label, name, + onOpen: actions.onOpen, ...(inputRef ? { inputRef } : {}), }, ownerState: props, 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 afb1302cf103..7f6134033556 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 @@ -11,7 +11,11 @@ import { PickersModalDialogSlotProps, } from '../../components/PickersModalDialog'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models'; +import { + BaseSingleInputFieldPropsInPickerSlots, + FieldSection, + PickerValidDate, +} from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -45,7 +49,7 @@ export interface ExportedUseMobilePickerSlotProps< > extends PickersModalDialogSlotProps, ExportedPickersLayoutSlotProps { field?: SlotComponentPropsFromProps< - BaseSingleInputFieldProps< + BaseSingleInputFieldPropsInPickerSlots< TDate | null, TDate, FieldSection, diff --git a/packages/x-date-pickers/src/models/fields.ts b/packages/x-date-pickers/src/models/fields.ts index fbd88d920e5b..be1ed5734b82 100644 --- a/packages/x-date-pickers/src/models/fields.ts +++ b/packages/x-date-pickers/src/models/fields.ts @@ -174,6 +174,17 @@ export type BaseSingleInputFieldProps< > = BaseFieldProps & BaseForwardedSingleInputFieldProps; +export type BaseSingleInputFieldPropsInPickerSlots< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TEnableAccessibleFieldDOMStructure extends boolean, + TError, +> = Omit< + BaseSingleInputFieldProps, + 'onOpen' +>; + /** * Props the text field receives when used with a single input picker. * Only contains what the MUI components are passing to the text field, not what users can pass using the `props.slotProps.field` and `props.slotProps.textField`. From 66574c346c32c40aecbe16f8a2210ea4711f059b Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 10:58:46 +0200 Subject: [PATCH 07/33] Fix types --- .../useDesktopRangePicker.tsx | 41 +++++++----------- .../hooks/useEnrichedRangePickerFieldProps.ts | 42 +++++++++++++------ .../useMobileRangePicker.tsx | 41 +++++++----------- .../x-date-pickers-pro/src/models/fields.ts | 11 +++++ 4 files changed, 69 insertions(+), 66 deletions(-) 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 55d56d9b6ca5..16c3e0a66776 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 @@ -12,21 +12,19 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, } from '@mui/x-date-pickers/internals'; -import { - PickerValidDate, - FieldRef, - BaseSingleInputFieldProps, - InferError, -} from '@mui/x-date-pickers/models'; +import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; import { DesktopRangePickerAdditionalViewProps, UseDesktopRangePickerParams, UseDesktopRangePickerProps, UseDesktopRangePickerSlotProps, } from './useDesktopRangePicker.types'; -import { useEnrichedRangePickerFieldProps } from '../useEnrichedRangePickerFieldProps'; +import { + RangePickerPropsForFieldSlot, + useEnrichedRangePickerFieldProps, +} from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; -import { DateRange, BaseMultiInputFieldProps, RangeFieldSection } from '../../../models'; +import { DateRange, RangeFieldSection } from '../../../models'; import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); @@ -138,24 +136,11 @@ export const useDesktopRangePicker = < const fieldProps = useSlotProps< typeof Field, UseDesktopRangePickerSlotProps['field'], - | Partial< - BaseSingleInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - InferError - > - > - | Partial< - BaseMultiInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - InferError - > - >, + RangePickerPropsForFieldSlot< + TDate, + TEnableAccessibleFieldDOMStructure, + InferError + >, TExternalProps >({ elementType: Field, @@ -172,6 +157,7 @@ export const useDesktopRangePicker = < selectedSections, onSelectedSectionsChange, timezone, + onOpen: actions.onOpen, autoFocus: autoFocus && !props.open, ref: fieldContainerRef, ...(fieldType === 'single-input' ? { inputRef, name } : {}), @@ -183,7 +169,8 @@ export const useDesktopRangePicker = < TDate, TView, TEnableAccessibleFieldDOMStructure, - InferError + InferError, + typeof fieldProps >({ wrapperVariant: 'desktop', fieldType, 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 92161a1d50da..28f6b786794c 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -19,7 +19,6 @@ import { } from '@mui/x-date-pickers/hooks'; import { PickersInputLocaleText } from '@mui/x-date-pickers/locales'; import { - BaseFieldProps, onSpaceOrEnter, UsePickerResponse, WrapperVariant, @@ -36,6 +35,7 @@ import { RangePosition, FieldType, UseDateRangeFieldProps, + BaseMultiInputFieldPropsInPickerSlots, } from '../../models'; import { UseRangePositionResponse } from './useRangePosition'; @@ -64,7 +64,7 @@ export interface RangePickerFieldSlotProps< TEnableAccessibleFieldDOMStructure extends boolean, > extends UseClearableFieldSlotProps { field?: SlotComponentPropsFromProps< - BaseMultiInputFieldProps< + BaseMultiInputFieldPropsInPickerSlots< DateRange, TDate, RangeFieldSection, @@ -83,21 +83,33 @@ export interface RangePickerFieldSlotProps< >; } +export type RangePickerPropsForFieldSlot< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, + TError, +> = + | BaseSingleInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > + | BaseMultiInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + >; + export interface UseEnrichedRangePickerFieldPropsParams< TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - FieldProps extends BaseFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > = BaseFieldProps< - DateRange, + FieldProps extends RangePickerPropsForFieldSlot< TDate, - RangeFieldSection, TEnableAccessibleFieldDOMStructure, TError >, @@ -451,12 +463,18 @@ export const useEnrichedRangePickerFieldProps = < TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, + FieldProps extends RangePickerPropsForFieldSlot< + TDate, + TEnableAccessibleFieldDOMStructure, + TError + >, >( params: UseEnrichedRangePickerFieldPropsParams< TDate, TView, TEnableAccessibleFieldDOMStructure, - TError + TError, + FieldProps >, ) => { /* eslint-disable react-hooks/rules-of-hooks */ 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 518914bdb1b5..8c7009982747 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 @@ -11,12 +11,7 @@ import { ExportedBaseTabsProps, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; -import { - PickerValidDate, - FieldRef, - BaseSingleInputFieldProps, - InferError, -} from '@mui/x-date-pickers/models'; +import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; import useId from '@mui/utils/useId'; import { MobileRangePickerAdditionalViewProps, @@ -24,9 +19,12 @@ import { UseMobileRangePickerProps, UseMobileRangePickerSlotProps, } from './useMobileRangePicker.types'; -import { useEnrichedRangePickerFieldProps } from '../useEnrichedRangePickerFieldProps'; +import { + RangePickerPropsForFieldSlot, + useEnrichedRangePickerFieldProps, +} from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; -import { DateRange, BaseMultiInputFieldProps, RangeFieldSection } from '../../../models'; +import { DateRange, RangeFieldSection } from '../../../models'; import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); @@ -114,24 +112,11 @@ export const useMobileRangePicker = < const fieldProps = useSlotProps< typeof Field, UseMobileRangePickerSlotProps['field'], - | Partial< - BaseSingleInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - InferError - > - > - | Partial< - BaseMultiInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - InferError - > - >, + RangePickerPropsForFieldSlot< + TDate, + TEnableAccessibleFieldDOMStructure, + InferError + >, TExternalProps >({ elementType: Field, @@ -148,6 +133,7 @@ export const useMobileRangePicker = < selectedSections, onSelectedSectionsChange, timezone, + onOpen: actions.onOpen, ...(fieldType === 'single-input' ? { inputRef, name } : {}), }, ownerState: props, @@ -159,7 +145,8 @@ export const useMobileRangePicker = < TDate, TView, TEnableAccessibleFieldDOMStructure, - InferError + InferError, + typeof fieldProps >({ wrapperVariant: 'mobile', fieldType, diff --git a/packages/x-date-pickers-pro/src/models/fields.ts b/packages/x-date-pickers-pro/src/models/fields.ts index 169c946d77c3..4670bd6519e5 100644 --- a/packages/x-date-pickers-pro/src/models/fields.ts +++ b/packages/x-date-pickers-pro/src/models/fields.ts @@ -95,6 +95,17 @@ export interface BaseMultiInputFieldProps< }; } +export type BaseMultiInputFieldPropsInPickerSlots< + TValue, + TDate extends PickerValidDate, + TSection extends FieldSection, + TEnableAccessibleFieldDOMStructure extends boolean, + TError, +> = Omit< + BaseMultiInputFieldProps, + 'onOpen' +>; + /** * Props the text field receives when used with a multi input picker. * Only contains what the MUI components are passing to the text field, not what users can pass using the `props.slotProps.textField`. From 00c6329304fa43772843737912240801ee3f6f5c Mon Sep 17 00:00:00 2001 From: delangle Date: Fri, 13 Sep 2024 11:08:23 +0200 Subject: [PATCH 08/33] Fix --- .../useDesktopRangePicker.tsx | 4 +- .../hooks/useEnrichedRangePickerFieldProps.ts | 95 ++++++++++--------- .../useMobileRangePicker.tsx | 4 +- .../src/hooks/useFieldPlaceholder.ts | 1 + scripts/x-date-pickers-pro.exports.json | 3 + scripts/x-date-pickers.exports.json | 2 + 6 files changed, 60 insertions(+), 49 deletions(-) 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 16c3e0a66776..b157c4943627 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 @@ -137,6 +137,7 @@ export const useDesktopRangePicker = < typeof Field, UseDesktopRangePickerSlotProps['field'], RangePickerPropsForFieldSlot< + boolean, TDate, TEnableAccessibleFieldDOMStructure, InferError @@ -169,8 +170,7 @@ export const useDesktopRangePicker = < TDate, TView, TEnableAccessibleFieldDOMStructure, - InferError, - typeof fieldProps + InferError >({ wrapperVariant: 'desktop', fieldType, 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 28f6b786794c..fb96c04f3d7b 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -84,35 +84,36 @@ export interface RangePickerFieldSlotProps< } export type RangePickerPropsForFieldSlot< + TIsSingleInput extends boolean, TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, TError, > = - | BaseSingleInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > - | BaseMultiInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - >; + | (TIsSingleInput extends true + ? BaseSingleInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > + : never) + | (TIsSingleInput extends false + ? BaseMultiInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > + : never); export interface UseEnrichedRangePickerFieldPropsParams< + TIsSingleInput extends boolean, TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - FieldProps extends RangePickerPropsForFieldSlot< - TDate, - TEnableAccessibleFieldDOMStructure, - TError - >, > extends Pick< UsePickerResponse, TView, RangeFieldSection, any>, 'open' | 'actions' @@ -128,7 +129,12 @@ export interface UseEnrichedRangePickerFieldPropsParams< localeText: PickersInputLocaleText | undefined; pickerSlotProps: RangePickerFieldSlotProps | undefined; pickerSlots: RangePickerFieldSlots | undefined; - fieldProps: FieldProps; + fieldProps: RangePickerPropsForFieldSlot< + TIsSingleInput, + TDate, + TEnableAccessibleFieldDOMStructure, + TError + >; anchorRef?: React.Ref; currentView?: TView | null; initialView?: TView; @@ -163,17 +169,11 @@ const useMultiInputFieldSlotProps = < startFieldRef, endFieldRef, }: UseEnrichedRangePickerFieldPropsParams< + false, TDate, TView, TEnableAccessibleFieldDOMStructure, - TError, - BaseMultiInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > + TError >) => { type ReturnType = BaseMultiInputFieldProps< DateRange, @@ -348,17 +348,11 @@ const useSingleInputFieldSlotProps = < anchorRef, currentView, }: UseEnrichedRangePickerFieldPropsParams< + true, TDate, TView, TEnableAccessibleFieldDOMStructure, - TError, - BaseSingleInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > + TError >) => { type ReturnType = BaseSingleInputFieldProps< DateRange, @@ -463,18 +457,13 @@ export const useEnrichedRangePickerFieldProps = < TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, - FieldProps extends RangePickerPropsForFieldSlot< - TDate, - TEnableAccessibleFieldDOMStructure, - TError - >, >( params: UseEnrichedRangePickerFieldPropsParams< + boolean, TDate, TView, TEnableAccessibleFieldDOMStructure, - TError, - FieldProps + TError >, ) => { /* eslint-disable react-hooks/rules-of-hooks */ @@ -488,9 +477,25 @@ export const useEnrichedRangePickerFieldProps = < } if (params.fieldType === 'multi-input') { - return useMultiInputFieldSlotProps(params); + return useMultiInputFieldSlotProps( + params as unknown as UseEnrichedRangePickerFieldPropsParams< + false, + TDate, + TView, + TEnableAccessibleFieldDOMStructure, + TError + >, + ); } - return useSingleInputFieldSlotProps(params); + return useSingleInputFieldSlotProps( + params as UseEnrichedRangePickerFieldPropsParams< + true, + TDate, + TView, + TEnableAccessibleFieldDOMStructure, + TError + >, + ); /* eslint-enable react-hooks/rules-of-hooks */ }; 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 8c7009982747..1ad0e4f915d3 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 @@ -113,6 +113,7 @@ export const useMobileRangePicker = < typeof Field, UseMobileRangePickerSlotProps['field'], RangePickerPropsForFieldSlot< + boolean, TDate, TEnableAccessibleFieldDOMStructure, InferError @@ -145,8 +146,7 @@ export const useMobileRangePicker = < TDate, TView, TEnableAccessibleFieldDOMStructure, - InferError, - typeof fieldProps + InferError >({ wrapperVariant: 'mobile', fieldType, diff --git a/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts b/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts index ad5d9a34669b..7257826be94b 100644 --- a/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts +++ b/packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts @@ -1,3 +1,4 @@ +'use client'; import * as React from 'react'; import { useRtl } from '@mui/system/RtlProvider'; import { useUtils } from '../internals/hooks/useUtils'; diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 24beed350813..7dcf14b46a88 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -5,9 +5,11 @@ { "name": "ArrowLeftIcon", "kind": "Variable" }, { "name": "ArrowRightIcon", "kind": "Variable" }, { "name": "BaseMultiInputFieldProps", "kind": "Interface" }, + { "name": "BaseMultiInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseMultiInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BasePickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BaseSingleInputFieldProps", "kind": "TypeAlias" }, + { "name": "BaseSingleInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseSingleInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BuiltInFieldTextFieldProps", "kind": "TypeAlias" }, { "name": "CalendarIcon", "kind": "Variable" }, @@ -413,6 +415,7 @@ { "name": "UseDateRangeFieldProps", "kind": "Interface" }, { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, + { "name": "useFieldPlaceholder", "kind": "Variable" }, { "name": "UseMultiInputDateRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputDateRangeFieldProps", "kind": "Interface" }, { "name": "UseMultiInputDateTimeRangeFieldComponentProps", "kind": "TypeAlias" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 4ae16b168cba..0358995f9917 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -5,6 +5,7 @@ { "name": "ArrowLeftIcon", "kind": "Variable" }, { "name": "ArrowRightIcon", "kind": "Variable" }, { "name": "BaseSingleInputFieldProps", "kind": "TypeAlias" }, + { "name": "BaseSingleInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseSingleInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BuiltInFieldTextFieldProps", "kind": "TypeAlias" }, { "name": "CalendarIcon", "kind": "Variable" }, @@ -304,6 +305,7 @@ { "name": "UseDateFieldProps", "kind": "Interface" }, { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, + { "name": "useFieldPlaceholder", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "useSplitFieldProps", "kind": "Variable" }, From 15fbfec2139df42a32607add2362f4c5f24d6c07 Mon Sep 17 00:00:00 2001 From: delangle Date: Tue, 17 Sep 2024 12:17:47 +0200 Subject: [PATCH 09/33] Improve doc --- docs/data/date-pickers/custom-field/custom-field.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index 20ca0d4c7f0c..162f11ebbaf6 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -151,10 +151,6 @@ Learn more about the accessible DOM structure and its difference compared to the ## Usage with another UI -### Using a read-only `TextField` - -{{"demo": "custom-behavior/ReadonlyMaterialTextField.js", "defaultCodeOpen": false}} - ### Using an `Autocomplete` If your user can only select a value in a small list of available dates, @@ -162,10 +158,17 @@ you can replace the field with an `Autocomplete` listing those dates: {{"demo": "PickerWithAutocompleteField.js", "defaultCodeOpen": false}} +### Using a read-only `TextField` + +If you only want to allow the user to pick a value through the views, +but you still want the UI to look like a `TextField`, you can replace the field with a read-only `TextField`: + +{{"demo": "custom-behavior/ReadonlyMaterialTextField.js", "defaultCodeOpen": false}} + ### Using a `Button` If you only want to allow the user to pick a value through the views, -you can replace the field with a `Button`: +and you don't want the UI to look like a `TextField`, you can replace the field with a `Button`: {{"demo": "PickerWithButtonField.js", "defaultCodeOpen": false}} From 26a213536a9961dfdb5b001824cfbda6e661225e Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 11:53:09 +0200 Subject: [PATCH 10/33] Try to move onOpen to a context --- .../ReadonlyMaterialTextField.js | 14 +++-- .../ReadonlyMaterialTextField.tsx | 14 +++-- .../useDesktopRangePicker.tsx | 56 ++++++++++-------- .../hooks/useEnrichedRangePickerFieldProps.ts | 3 +- .../useMobileRangePicker.tsx | 36 +++++++----- .../x-date-pickers-pro/src/models/fields.ts | 11 ---- .../DesktopDatePicker/DesktopDatePicker.tsx | 2 +- .../DesktopDateTimePicker.tsx | 2 +- .../DesktopTimePicker/DesktopTimePicker.tsx | 2 +- .../src/MobileDatePicker/MobileDatePicker.tsx | 2 +- .../MobileDateTimePicker.tsx | 2 +- .../src/MobileTimePicker/MobileTimePicker.tsx | 2 +- packages/x-date-pickers/src/hooks/index.tsx | 2 + .../src/hooks/usePickersFieldContext.ts | 28 +++++++++ .../components/PickersFieldProvider.tsx | 18 ++++++ .../useDesktopPicker/useDesktopPicker.tsx | 58 +++++++++++-------- .../useDesktopPicker.types.ts | 8 +-- .../hooks/useMobilePicker/useMobilePicker.tsx | 38 +++++++----- .../useMobilePicker/useMobilePicker.types.ts | 8 +-- .../x-date-pickers/src/internals/index.ts | 2 + .../src/internals/models/fields.ts | 1 - packages/x-date-pickers/src/models/fields.ts | 11 ---- 22 files changed, 193 insertions(+), 127 deletions(-) create mode 100644 packages/x-date-pickers/src/hooks/usePickersFieldContext.ts create mode 100644 packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js index 9714150e884c..7ca1f137f3b1 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js @@ -1,18 +1,24 @@ import * as React from 'react'; +import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; -import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; -import TextField from '@mui/material/TextField'; +import { + useSplitFieldProps, + useFieldPlaceholder, + usePickersFieldContext, +} from '@mui/x-date-pickers/hooks'; function ReadonlyDateField(props) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - const { value, timezone, format, onOpen } = internalProps; + const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; + const pickerContext = usePickersFieldContext(); + const placeholder = useFieldPlaceholder(internalProps); const { hasValidationError } = useValidation({ validator: validateDate, @@ -28,7 +34,7 @@ function ReadonlyDateField(props) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={onOpen} + onClick={pickerContext.onOpen} /> ); } diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx index e55dc5224358..3cb0ee7f002d 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx @@ -1,18 +1,24 @@ import * as React from 'react'; import { Dayjs } from 'dayjs'; +import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps } from '@mui/x-date-pickers/DatePicker'; import { DateFieldInPickerProps } from '@mui/x-date-pickers/DateField'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; -import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks'; -import TextField from '@mui/material/TextField'; +import { + useSplitFieldProps, + useFieldPlaceholder, + usePickersFieldContext, +} from '@mui/x-date-pickers/hooks'; function ReadonlyDateField(props: DateFieldInPickerProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - const { value, timezone, format, onOpen } = internalProps; + const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; + const pickerContext = usePickersFieldContext(); + const placeholder = useFieldPlaceholder(internalProps); const { hasValidationError } = useValidation({ validator: validateDate, @@ -28,7 +34,7 @@ function ReadonlyDateField(props: DateFieldInPickerProps) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={onOpen} + onClick={pickerContext.onOpen} /> ); } 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 b157c4943627..09d0fc443eba 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 { ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, + PickersFieldContextValue, + PickersFieldProvider, } from '@mui/x-date-pickers/internals'; import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; import { @@ -158,7 +160,6 @@ export const useDesktopRangePicker = < selectedSections, onSelectedSectionsChange, timezone, - onOpen: actions.onOpen, autoFocus: autoFocus && !props.open, ref: fieldContainerRef, ...(fieldType === 'single-input' ? { inputRef, name } : {}), @@ -209,32 +210,39 @@ export const useDesktopRangePicker = < }; const Layout = slots?.layout ?? PickersLayout; + const contextValue = React.useMemo( + () => ({ onOpen: actions.onOpen }), + [actions.onOpen], + ); + const renderPicker = () => ( - - - - + + + - {renderCurrentView()} - - - + + {renderCurrentView()} + + + + ); return { 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 fb96c04f3d7b..9c0bde6d9d5b 100644 --- a/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts +++ b/packages/x-date-pickers-pro/src/internals/hooks/useEnrichedRangePickerFieldProps.ts @@ -35,7 +35,6 @@ import { RangePosition, FieldType, UseDateRangeFieldProps, - BaseMultiInputFieldPropsInPickerSlots, } from '../../models'; import { UseRangePositionResponse } from './useRangePosition'; @@ -64,7 +63,7 @@ export interface RangePickerFieldSlotProps< TEnableAccessibleFieldDOMStructure extends boolean, > extends UseClearableFieldSlotProps { field?: SlotComponentPropsFromProps< - BaseMultiInputFieldPropsInPickerSlots< + BaseMultiInputFieldProps< DateRange, TDate, RangeFieldSection, 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 1ad0e4f915d3..d58c24ba6e3e 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 { ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, + PickersFieldContextValue, + PickersFieldProvider, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; @@ -134,7 +136,6 @@ export const useMobileRangePicker = < selectedSections, onSelectedSectionsChange, timezone, - onOpen: actions.onOpen, ...(fieldType === 'single-input' ? { inputRef, name } : {}), }, ownerState: props, @@ -214,20 +215,27 @@ export const useMobileRangePicker = < }, }; + const contextValue = React.useMemo( + () => ({ onOpen: actions.onOpen }), + [actions.onOpen], + ); + const renderPicker = () => ( - - - - - {renderCurrentView()} - - - + + + + + + {renderCurrentView()} + + + + ); return { diff --git a/packages/x-date-pickers-pro/src/models/fields.ts b/packages/x-date-pickers-pro/src/models/fields.ts index 4670bd6519e5..169c946d77c3 100644 --- a/packages/x-date-pickers-pro/src/models/fields.ts +++ b/packages/x-date-pickers-pro/src/models/fields.ts @@ -95,17 +95,6 @@ export interface BaseMultiInputFieldProps< }; } -export type BaseMultiInputFieldPropsInPickerSlots< - TValue, - TDate extends PickerValidDate, - TSection extends FieldSection, - TEnableAccessibleFieldDOMStructure extends boolean, - TError, -> = Omit< - BaseMultiInputFieldProps, - 'onOpen' ->; - /** * Props the text field receives when used with a multi input picker. * Only contains what the MUI components are passing to the text field, not what users can pass using the `props.slotProps.textField`. diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx index 86d5a290dc68..6fede2f69466 100644 --- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx @@ -72,7 +72,7 @@ const DesktopDatePicker = React.forwardRef(function DesktopDatePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx index 3fc3904e477a..421f595a40b8 100644 --- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx @@ -197,7 +197,7 @@ const DesktopDateTimePicker = React.forwardRef(function DesktopDateTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx index 7ff550001e1f..966c729b6365 100644 --- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx +++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx @@ -105,7 +105,7 @@ const DesktopTimePicker = React.forwardRef(function DesktopTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx index 72b4d353ad6c..31d270574cb2 100644 --- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx +++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx @@ -69,7 +69,7 @@ const MobileDatePicker = React.forwardRef(function MobileDatePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx index 1d75463f9a78..ec10a6296202 100644 --- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx @@ -79,7 +79,7 @@ const MobileDateTimePicker = React.forwardRef(function MobileDateTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx index e49287194d6c..5898915dfd1b 100644 --- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx +++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx @@ -72,7 +72,7 @@ const MobileTimePicker = React.forwardRef(function MobileTimePicker< slotProps: { ...defaultizedProps.slotProps, field: (ownerState: any) => ({ - ...(resolveComponentProps(defaultizedProps.slotProps?.field, ownerState) as any), + ...resolveComponentProps(defaultizedProps.slotProps?.field, ownerState), ...extractValidationProps(defaultizedProps), ref, }), diff --git a/packages/x-date-pickers/src/hooks/index.tsx b/packages/x-date-pickers/src/hooks/index.tsx index c19ca7b21d6e..079dc26aa423 100644 --- a/packages/x-date-pickers/src/hooks/index.tsx +++ b/packages/x-date-pickers/src/hooks/index.tsx @@ -11,3 +11,5 @@ export { usePickersTranslations } from './usePickersTranslations'; export { useSplitFieldProps } from './useSplitFieldProps'; export { useFieldPlaceholder } from './useFieldPlaceholder'; + +export { usePickersFieldContext } from './usePickersFieldContext'; diff --git a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts new file mode 100644 index 000000000000..1448bb8dff0f --- /dev/null +++ b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { + PickersFieldContext, + PickersFieldContextValue, +} from '../internals/components/PickersFieldProvider'; + +/** + * Returns the context passed by the picker that wraps the current field. + * If the field is used as a standalone component, the context will be `null`. + */ +export const usePickersFieldContext = ( + params: { isOptional: TOptional } = { isOptional: false as TOptional }, +) => { + const value = React.useContext(PickersFieldContext); + if (!params.isOptional && value == null) { + throw new Error( + [ + 'MUI X: The `usePickersFieldContext` hook was used outside of the component tree of a picker.', + 'If your field component is usable as a standalone component, then to use the hook as follow:', + '`usePickersFieldContext({ isOptional: true })`', + ].join('\n'), + ); + } + + return value as TOptional extends false + ? PickersFieldContextValue + : PickersFieldContextValue | null; +}; diff --git a/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx new file mode 100644 index 000000000000..738ea9726050 --- /dev/null +++ b/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; + +export const PickersFieldContext = React.createContext(null); + +export function PickersFieldProvider(props: PickersFieldProviderProps) { + const { value, children } = props; + + return {children}; +} + +interface PickersFieldProviderProps { + value: PickersFieldContextValue; + children: React.ReactNode; +} + +export interface PickersFieldContextValue { + onOpen: (event: React.UIEvent) => void; +} 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 673a80006898..6989344ec527 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -22,6 +22,10 @@ import { InferError, } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; +import { + PickersFieldContextValue, + PickersFieldProvider, +} from '../../components/PickersFieldProvider'; /** * Hook managing all the single-date desktop pickers: @@ -156,7 +160,6 @@ export const useDesktopPicker = < timezone, label, name, - onOpen: actions.onOpen, autoFocus: autoFocus && !props.open, focused: open ? true : undefined, ...(inputRef ? { inputRef } : {}), @@ -212,30 +215,37 @@ export const useDesktopPicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); + const contextValue = React.useMemo( + () => ({ onOpen: actions.onOpen }), + [actions.onOpen], + ); + const renderPicker = () => ( - - - - - {renderCurrentView()} - - - + + + + + + {renderCurrentView()} + + + + ); return { renderPicker }; 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 426a2ba4b70d..494e25e6b25a 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,11 +10,7 @@ import { } from '../../models/props/basePickerProps'; import { PickersPopperSlots, PickersPopperSlotProps } from '../../components/PickersPopper'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { - BaseSingleInputFieldPropsInPickerSlots, - FieldSection, - PickerValidDate, -} from '../../../models'; +import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -82,7 +78,7 @@ export interface ExportedUseDesktopPickerSlotProps< ExportedPickersLayoutSlotProps, UseClearableFieldSlotProps { field?: SlotComponentPropsFromProps< - BaseSingleInputFieldPropsInPickerSlots< + BaseSingleInputFieldProps< TDate | null, TDate, FieldSection, 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 208fd5721387..9ed3ab8a8dd8 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -20,6 +20,10 @@ import { InferError, } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; +import { + PickersFieldContextValue, + PickersFieldProvider, +} from '../../components/PickersFieldProvider'; /** * Hook managing all the single-date mobile pickers: @@ -118,7 +122,6 @@ export const useMobilePicker = < timezone, label, name, - onOpen: actions.onOpen, ...(inputRef ? { inputRef } : {}), }, ownerState: props, @@ -159,20 +162,27 @@ export const useMobilePicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); + const contextValue = React.useMemo( + () => ({ onOpen: actions.onOpen }), + [actions.onOpen], + ); + const renderPicker = () => ( - - - - - {renderCurrentView()} - - - + + + + + + {renderCurrentView()} + + + + ); return { renderPicker }; 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 7f6134033556..afb1302cf103 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 @@ -11,11 +11,7 @@ import { PickersModalDialogSlotProps, } from '../../components/PickersModalDialog'; import { UsePickerParams, UsePickerProps } from '../usePicker'; -import { - BaseSingleInputFieldPropsInPickerSlots, - FieldSection, - PickerValidDate, -} from '../../../models'; +import { BaseSingleInputFieldProps, FieldSection, PickerValidDate } from '../../../models'; import { ExportedPickersLayoutSlots, ExportedPickersLayoutSlotProps, @@ -49,7 +45,7 @@ export interface ExportedUseMobilePickerSlotProps< > extends PickersModalDialogSlotProps, ExportedPickersLayoutSlotProps { field?: SlotComponentPropsFromProps< - BaseSingleInputFieldPropsInPickerSlots< + BaseSingleInputFieldProps< TDate | null, TDate, FieldSection, diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index 6bd9dab4cd19..e45ad46ac413 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -4,6 +4,8 @@ export type { PickersArrowSwitcherSlots, PickersArrowSwitcherSlotProps, } from './components/PickersArrowSwitcher'; +export { PickersFieldProvider } from './components/PickersFieldProvider'; +export type { PickersFieldContextValue } from './components/PickersFieldProvider'; export { PickersModalDialog } from './components/PickersModalDialog'; export type { PickersModalDialogSlots, diff --git a/packages/x-date-pickers/src/internals/models/fields.ts b/packages/x-date-pickers/src/internals/models/fields.ts index 032622ed41ce..e02b43315f56 100644 --- a/packages/x-date-pickers/src/internals/models/fields.ts +++ b/packages/x-date-pickers/src/internals/models/fields.ts @@ -18,5 +18,4 @@ export interface BaseFieldProps< format?: string; disabled?: boolean; ref?: React.Ref; - onOpen: (event: React.UIEvent) => void; } diff --git a/packages/x-date-pickers/src/models/fields.ts b/packages/x-date-pickers/src/models/fields.ts index be1ed5734b82..fbd88d920e5b 100644 --- a/packages/x-date-pickers/src/models/fields.ts +++ b/packages/x-date-pickers/src/models/fields.ts @@ -174,17 +174,6 @@ export type BaseSingleInputFieldProps< > = BaseFieldProps & BaseForwardedSingleInputFieldProps; -export type BaseSingleInputFieldPropsInPickerSlots< - TValue, - TDate extends PickerValidDate, - TSection extends FieldSection, - TEnableAccessibleFieldDOMStructure extends boolean, - TError, -> = Omit< - BaseSingleInputFieldProps, - 'onOpen' ->; - /** * Props the text field receives when used with a single input picker. * Only contains what the MUI components are passing to the text field, not what users can pass using the `props.slotProps.field` and `props.slotProps.textField`. From 676aa657965c021778d26bcb9b807d230fa349f4 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 11:58:51 +0200 Subject: [PATCH 11/33] Remove TS changes --- .../useDesktopRangePicker.tsx | 38 +++++--- .../hooks/useEnrichedRangePickerFieldProps.ts | 88 +++++++------------ .../useMobileRangePicker.tsx | 38 +++++--- 3 files changed, 85 insertions(+), 79 deletions(-) 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 09d0fc443eba..0c876611e001 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 @@ -14,19 +14,21 @@ import { PickersFieldContextValue, PickersFieldProvider, } from '@mui/x-date-pickers/internals'; -import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; +import { + PickerValidDate, + FieldRef, + BaseSingleInputFieldProps, + InferError, +} from '@mui/x-date-pickers/models'; import { DesktopRangePickerAdditionalViewProps, UseDesktopRangePickerParams, UseDesktopRangePickerProps, UseDesktopRangePickerSlotProps, } from './useDesktopRangePicker.types'; -import { - RangePickerPropsForFieldSlot, - useEnrichedRangePickerFieldProps, -} from '../useEnrichedRangePickerFieldProps'; +import { useEnrichedRangePickerFieldProps } from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; -import { DateRange, RangeFieldSection } from '../../../models'; +import { DateRange, BaseMultiInputFieldProps, RangeFieldSection } from '../../../models'; import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); @@ -138,12 +140,24 @@ export const useDesktopRangePicker = < const fieldProps = useSlotProps< typeof Field, UseDesktopRangePickerSlotProps['field'], - RangePickerPropsForFieldSlot< - boolean, - TDate, - TEnableAccessibleFieldDOMStructure, - InferError - >, + | Partial< + BaseSingleInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + InferError + > + > + | Partial< + BaseMultiInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + InferError + > + >, TExternalProps >({ elementType: Field, 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 9c0bde6d9d5b..92161a1d50da 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,7 @@ import { } from '@mui/x-date-pickers/hooks'; import { PickersInputLocaleText } from '@mui/x-date-pickers/locales'; import { + BaseFieldProps, onSpaceOrEnter, UsePickerResponse, WrapperVariant, @@ -82,37 +83,24 @@ export interface RangePickerFieldSlotProps< >; } -export type RangePickerPropsForFieldSlot< - TIsSingleInput extends boolean, - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, - TError, -> = - | (TIsSingleInput extends true - ? BaseSingleInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > - : never) - | (TIsSingleInput extends false - ? BaseMultiInputFieldProps< - DateRange, - TDate, - RangeFieldSection, - TEnableAccessibleFieldDOMStructure, - TError - > - : never); - export interface UseEnrichedRangePickerFieldPropsParams< - TIsSingleInput extends boolean, TDate extends PickerValidDate, TView extends DateOrTimeViewWithMeridiem, TEnableAccessibleFieldDOMStructure extends boolean, TError, + FieldProps extends BaseFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > = BaseFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + >, > extends Pick< UsePickerResponse, TView, RangeFieldSection, any>, 'open' | 'actions' @@ -128,12 +116,7 @@ export interface UseEnrichedRangePickerFieldPropsParams< localeText: PickersInputLocaleText | undefined; pickerSlotProps: RangePickerFieldSlotProps | undefined; pickerSlots: RangePickerFieldSlots | undefined; - fieldProps: RangePickerPropsForFieldSlot< - TIsSingleInput, - TDate, - TEnableAccessibleFieldDOMStructure, - TError - >; + fieldProps: FieldProps; anchorRef?: React.Ref; currentView?: TView | null; initialView?: TView; @@ -168,11 +151,17 @@ const useMultiInputFieldSlotProps = < startFieldRef, endFieldRef, }: UseEnrichedRangePickerFieldPropsParams< - false, TDate, TView, TEnableAccessibleFieldDOMStructure, - TError + TError, + BaseMultiInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > >) => { type ReturnType = BaseMultiInputFieldProps< DateRange, @@ -347,11 +336,17 @@ const useSingleInputFieldSlotProps = < anchorRef, currentView, }: UseEnrichedRangePickerFieldPropsParams< - true, TDate, TView, TEnableAccessibleFieldDOMStructure, - TError + TError, + BaseSingleInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + TError + > >) => { type ReturnType = BaseSingleInputFieldProps< DateRange, @@ -458,7 +453,6 @@ export const useEnrichedRangePickerFieldProps = < TError, >( params: UseEnrichedRangePickerFieldPropsParams< - boolean, TDate, TView, TEnableAccessibleFieldDOMStructure, @@ -476,25 +470,9 @@ export const useEnrichedRangePickerFieldProps = < } if (params.fieldType === 'multi-input') { - return useMultiInputFieldSlotProps( - params as unknown as UseEnrichedRangePickerFieldPropsParams< - false, - TDate, - TView, - TEnableAccessibleFieldDOMStructure, - TError - >, - ); + return useMultiInputFieldSlotProps(params); } - return useSingleInputFieldSlotProps( - params as UseEnrichedRangePickerFieldPropsParams< - true, - TDate, - TView, - TEnableAccessibleFieldDOMStructure, - TError - >, - ); + return useSingleInputFieldSlotProps(params); /* eslint-enable react-hooks/rules-of-hooks */ }; 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 d58c24ba6e3e..0a077cf07054 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 @@ -13,7 +13,12 @@ import { PickersFieldProvider, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; -import { PickerValidDate, FieldRef, InferError } from '@mui/x-date-pickers/models'; +import { + PickerValidDate, + FieldRef, + BaseSingleInputFieldProps, + InferError, +} from '@mui/x-date-pickers/models'; import useId from '@mui/utils/useId'; import { MobileRangePickerAdditionalViewProps, @@ -21,12 +26,9 @@ import { UseMobileRangePickerProps, UseMobileRangePickerSlotProps, } from './useMobileRangePicker.types'; -import { - RangePickerPropsForFieldSlot, - useEnrichedRangePickerFieldProps, -} from '../useEnrichedRangePickerFieldProps'; +import { useEnrichedRangePickerFieldProps } from '../useEnrichedRangePickerFieldProps'; import { getReleaseInfo } from '../../utils/releaseInfo'; -import { DateRange, RangeFieldSection } from '../../../models'; +import { DateRange, BaseMultiInputFieldProps, RangeFieldSection } from '../../../models'; import { useRangePosition } from '../useRangePosition'; const releaseInfo = getReleaseInfo(); @@ -114,12 +116,24 @@ export const useMobileRangePicker = < const fieldProps = useSlotProps< typeof Field, UseMobileRangePickerSlotProps['field'], - RangePickerPropsForFieldSlot< - boolean, - TDate, - TEnableAccessibleFieldDOMStructure, - InferError - >, + | Partial< + BaseSingleInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + InferError + > + > + | Partial< + BaseMultiInputFieldProps< + DateRange, + TDate, + RangeFieldSection, + TEnableAccessibleFieldDOMStructure, + InferError + > + >, TExternalProps >({ elementType: Field, From 9f5f302b891538ca0c9099bb7823eb30673457bf Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 12:02:24 +0200 Subject: [PATCH 12/33] Fix --- packages/x-date-pickers/src/hooks/useSplitFieldProps.ts | 1 - scripts/x-date-pickers-pro.exports.json | 3 +-- scripts/x-date-pickers.exports.json | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts index 67bbe25e9d12..35a29a7bc094 100644 --- a/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts +++ b/packages/x-date-pickers/src/hooks/useSplitFieldProps.ts @@ -24,7 +24,6 @@ const SHARED_FIELD_INTERNAL_PROP_NAMES = [ 'disabled', 'readOnly', 'dateSeparator', - 'onOpen', ] as const; type InternalPropNames = diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 7dcf14b46a88..0833e97aea4e 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -5,11 +5,9 @@ { "name": "ArrowLeftIcon", "kind": "Variable" }, { "name": "ArrowRightIcon", "kind": "Variable" }, { "name": "BaseMultiInputFieldProps", "kind": "Interface" }, - { "name": "BaseMultiInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseMultiInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BasePickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BaseSingleInputFieldProps", "kind": "TypeAlias" }, - { "name": "BaseSingleInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseSingleInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BuiltInFieldTextFieldProps", "kind": "TypeAlias" }, { "name": "CalendarIcon", "kind": "Variable" }, @@ -423,6 +421,7 @@ { "name": "UseMultiInputTimeRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputTimeRangeFieldProps", "kind": "Interface" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, + { "name": "usePickersFieldContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "UseSingleInputDateRangeFieldProps", "kind": "Interface" }, { "name": "UseSingleInputDateTimeRangeFieldProps", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 0358995f9917..d77a6bf000fc 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -5,7 +5,6 @@ { "name": "ArrowLeftIcon", "kind": "Variable" }, { "name": "ArrowRightIcon", "kind": "Variable" }, { "name": "BaseSingleInputFieldProps", "kind": "TypeAlias" }, - { "name": "BaseSingleInputFieldPropsInPickerSlots", "kind": "TypeAlias" }, { "name": "BaseSingleInputPickersTextFieldProps", "kind": "TypeAlias" }, { "name": "BuiltInFieldTextFieldProps", "kind": "TypeAlias" }, { "name": "CalendarIcon", "kind": "Variable" }, @@ -307,6 +306,7 @@ { "name": "UseDateTimeFieldProps", "kind": "Interface" }, { "name": "useFieldPlaceholder", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, + { "name": "usePickersFieldContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "useSplitFieldProps", "kind": "Variable" }, { "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" }, From 9837ebf940de8026bb410549cd954e3797c612c5 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 12:05:00 +0200 Subject: [PATCH 13/33] Fix --- .../src/hooks/usePickersFieldContext.ts | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts index 1448bb8dff0f..8a8b4c6276d0 100644 --- a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts +++ b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts @@ -1,28 +1,18 @@ import * as React from 'react'; -import { - PickersFieldContext, - PickersFieldContextValue, -} from '../internals/components/PickersFieldProvider'; +import { PickersFieldContext } from '../internals/components/PickersFieldProvider'; /** * Returns the context passed by the picker that wraps the current field. - * If the field is used as a standalone component, the context will be `null`. */ -export const usePickersFieldContext = ( - params: { isOptional: TOptional } = { isOptional: false as TOptional }, -) => { +export const usePickersFieldContext = () => { const value = React.useContext(PickersFieldContext); - if (!params.isOptional && value == null) { + if (value == null) { throw new Error( [ - 'MUI X: The `usePickersFieldContext` hook was used outside of the component tree of a picker.', - 'If your field component is usable as a standalone component, then to use the hook as follow:', - '`usePickersFieldContext({ isOptional: true })`', + 'MUI X: The `usePickersFieldContext` can only be called in fields that are used as a slot of a picker component', ].join('\n'), ); } - return value as TOptional extends false - ? PickersFieldContextValue - : PickersFieldContextValue | null; + return value; }; From c9b090609d92dcd3a7c88b44f4135503f51657e7 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 12:13:49 +0200 Subject: [PATCH 14/33] Work --- .../useDesktopRangePicker.tsx | 51 ++++++++--------- .../useMobileRangePicker.tsx | 33 +++++------ .../src/hooks/usePickersFieldContext.ts | 2 +- .../components/PickersFieldProvider.tsx | 18 ------ .../internals/components/PickersProvider.tsx | 35 ++++++++++++ .../useDesktopPicker/useDesktopPicker.tsx | 56 +++++++++---------- .../hooks/useMobilePicker/useMobilePicker.tsx | 36 +++++------- .../x-date-pickers/src/internals/index.ts | 4 +- 8 files changed, 117 insertions(+), 118 deletions(-) delete mode 100644 packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx create mode 100644 packages/x-date-pickers/src/internals/components/PickersProvider.tsx 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 0c876611e001..5d1233a268c8 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 @@ -1,7 +1,6 @@ import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { useLicenseVerifier } from '@mui/x-license'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/PickersLayout'; import { executeInTheNextEventLoopTick, @@ -12,7 +11,7 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, PickersFieldContextValue, - PickersFieldProvider, + PickersProvider, } from '@mui/x-date-pickers/internals'; import { PickerValidDate, @@ -230,33 +229,31 @@ export const useDesktopRangePicker = < ); const renderPicker = () => ( - - - - + + + - - {renderCurrentView()} - - - - + {renderCurrentView()} + + + ); return { 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 0a077cf07054..0359e8132220 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 @@ -1,7 +1,6 @@ import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { useLicenseVerifier } from '@mui/x-license'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/PickersLayout'; import { usePicker, @@ -10,7 +9,7 @@ import { DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, PickersFieldContextValue, - PickersFieldProvider, + PickersProvider, } from '@mui/x-date-pickers/internals'; import { usePickersTranslations } from '@mui/x-date-pickers/hooks'; import { @@ -229,27 +228,25 @@ export const useMobileRangePicker = < }, }; - const contextValue = React.useMemo( + const fieldContextValue = React.useMemo( () => ({ onOpen: actions.onOpen }), [actions.onOpen], ); const renderPicker = () => ( - - - - - - {renderCurrentView()} - - - - + + + + + {renderCurrentView()} + + + ); return { diff --git a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts index 8a8b4c6276d0..7833d07f9094 100644 --- a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts +++ b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { PickersFieldContext } from '../internals/components/PickersFieldProvider'; +import { PickersFieldContext } from '../internals/components/PickersProvider'; /** * Returns the context passed by the picker that wraps the current field. diff --git a/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx deleted file mode 100644 index 738ea9726050..000000000000 --- a/packages/x-date-pickers/src/internals/components/PickersFieldProvider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import * as React from 'react'; - -export const PickersFieldContext = React.createContext(null); - -export function PickersFieldProvider(props: PickersFieldProviderProps) { - const { value, children } = props; - - return {children}; -} - -interface PickersFieldProviderProps { - value: PickersFieldContextValue; - children: React.ReactNode; -} - -export interface PickersFieldContextValue { - onOpen: (event: React.UIEvent) => void; -} diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx new file mode 100644 index 000000000000..00cfddcd5500 --- /dev/null +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { PickerValidDate } from '../../models'; +import { PickersInputLocaleText } from '../../locales'; +import { LocalizationProvider } from '../../LocalizationProvider'; + +export const PickersFieldContext = React.createContext(null); + +/** + * Provides the context for the various parts of a picker component: + * - fieldContextValue: the context for the field + * - localizationProvider: the translations passed through the props and through a parent LocalizationProvider. + * + * @ignore - do not document. + */ +export function PickersProvider( + props: PickersFieldProviderProps, +) { + const { fieldContextValue, localeText, children } = props; + + return ( + + {children} + + ); +} + +interface PickersFieldProviderProps { + fieldContextValue: PickersFieldContextValue; + localeText: PickersInputLocaleText | undefined; + children: React.ReactNode; +} + +export interface PickersFieldContextValue { + onOpen: (event: React.UIEvent) => void; +} 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 6989344ec527..644cdce5fd00 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -12,7 +12,6 @@ import { UseDesktopPickerSlotProps, } from './useDesktopPicker.types'; import { usePicker } from '../usePicker'; -import { LocalizationProvider } from '../../../LocalizationProvider'; import { PickersLayout } from '../../../PickersLayout'; import { FieldSection, @@ -22,10 +21,7 @@ import { InferError, } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { - PickersFieldContextValue, - PickersFieldProvider, -} from '../../components/PickersFieldProvider'; +import { PickersFieldContextValue, PickersProvider } from '../../components/PickersProvider'; /** * Hook managing all the single-date desktop pickers: @@ -215,37 +211,35 @@ export const useDesktopPicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); - const contextValue = React.useMemo( + const fieldContextValue = React.useMemo( () => ({ onOpen: actions.onOpen }), [actions.onOpen], ); const renderPicker = () => ( - - - - - - {renderCurrentView()} - - - - + + + + + {renderCurrentView()} + + + ); return { renderPicker }; 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 9ed3ab8a8dd8..3c972a4a336e 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -10,7 +10,6 @@ import { } from './useMobilePicker.types'; import { usePicker } from '../usePicker'; import { onSpaceOrEnter } from '../../utils/utils'; -import { LocalizationProvider } from '../../../LocalizationProvider'; import { PickersLayout } from '../../../PickersLayout'; import { FieldSection, @@ -20,10 +19,7 @@ import { InferError, } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { - PickersFieldContextValue, - PickersFieldProvider, -} from '../../components/PickersFieldProvider'; +import { PickersFieldContextValue, PickersProvider } from '../../components/PickersProvider'; /** * Hook managing all the single-date mobile pickers: @@ -162,27 +158,25 @@ export const useMobilePicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); - const contextValue = React.useMemo( + const fieldContextValue = React.useMemo( () => ({ onOpen: actions.onOpen }), [actions.onOpen], ); const renderPicker = () => ( - - - - - - {renderCurrentView()} - - - - + + + + + {renderCurrentView()} + + + ); return { renderPicker }; diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index e45ad46ac413..3698808a00be 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -4,8 +4,8 @@ export type { PickersArrowSwitcherSlots, PickersArrowSwitcherSlotProps, } from './components/PickersArrowSwitcher'; -export { PickersFieldProvider } from './components/PickersFieldProvider'; -export type { PickersFieldContextValue } from './components/PickersFieldProvider'; +export { PickersProvider as PickersFieldProvider } from './components/PickersProvider'; +export type { PickersFieldContextValue } from './components/PickersProvider'; export { PickersModalDialog } from './components/PickersModalDialog'; export type { PickersModalDialogSlots, From 9ca0721050bb8d500e9530a71ef26e727feb8745 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 12:23:32 +0200 Subject: [PATCH 15/33] Move logic to usePicker --- .../useDesktopRangePicker/useDesktopRangePicker.tsx | 9 ++------- .../useMobileRangePicker/useMobileRangePicker.tsx | 7 +------ .../hooks/useDesktopPicker/useDesktopPicker.tsx | 8 ++------ .../hooks/useMobilePicker/useMobilePicker.tsx | 8 ++------ .../src/internals/hooks/usePicker/usePicker.ts | 10 ++++++++++ .../src/internals/hooks/usePicker/usePicker.types.ts | 5 ++++- packages/x-date-pickers/src/internals/index.ts | 3 +-- 7 files changed, 22 insertions(+), 28 deletions(-) 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 5d1233a268c8..bd13b992836a 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 @@ -10,7 +10,6 @@ import { ExportedBaseToolbarProps, DateOrTimeViewWithMeridiem, ExportedBaseTabsProps, - PickersFieldContextValue, PickersProvider, } from '@mui/x-date-pickers/internals'; import { @@ -96,6 +95,7 @@ export const useDesktopRangePicker = < renderCurrentView, shouldRestoreFocus, fieldProps: pickerFieldProps, + fieldContextValue, } = usePicker< DateRange, TDate, @@ -223,13 +223,8 @@ export const useDesktopRangePicker = < }; const Layout = slots?.layout ?? PickersLayout; - const contextValue = React.useMemo( - () => ({ onOpen: actions.onOpen }), - [actions.onOpen], - ); - const renderPicker = () => ( - + , TDate, @@ -228,11 +228,6 @@ export const useMobileRangePicker = < }, }; - const fieldContextValue = React.useMemo( - () => ({ onOpen: actions.onOpen }), - [actions.onOpen], - ); - const renderPicker = () => ( 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 644cdce5fd00..62897088a791 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -21,7 +21,7 @@ import { InferError, } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { PickersFieldContextValue, PickersProvider } from '../../components/PickersProvider'; +import { PickersProvider } from '../../components/PickersProvider'; /** * Hook managing all the single-date desktop pickers: @@ -80,6 +80,7 @@ export const useDesktopPicker = < renderCurrentView, shouldRestoreFocus, fieldProps: pickerFieldProps, + fieldContextValue, } = usePicker({ ...pickerParams, props, @@ -211,11 +212,6 @@ export const useDesktopPicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); - const fieldContextValue = React.useMemo( - () => ({ onOpen: actions.onOpen }), - [actions.onOpen], - ); - const renderPicker = () => ( ({ ...pickerParams, props, @@ -158,11 +159,6 @@ export const useMobilePicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); - const fieldContextValue = React.useMemo( - () => ({ onOpen: actions.onOpen }), - [actions.onOpen], - ); - const renderPicker = () => ( ( + () => ({ onOpen: pickerValueResponse.actions.onOpen }), + [pickerValueResponse.actions.onOpen], + ); + return { // Picker value open: pickerValueResponse.open, @@ -84,5 +91,8 @@ export const usePicker = < // Picker layout layoutProps: pickerLayoutResponse.layoutProps, + + // Picker field + fieldContextValue, }; }; 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..d428f89db05b 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 @@ -13,6 +13,7 @@ import { import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps'; import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; +import { PickersFieldContextValue } from '../../components/PickersProvider'; /** * Props common to all picker headless implementations. @@ -64,4 +65,6 @@ export interface UsePickerResponse< TError, > extends Omit, 'viewProps' | 'layoutProps'>, Omit, 'layoutProps'>, - UsePickerLayoutPropsResponse {} + UsePickerLayoutPropsResponse { + fieldContextValue: PickersFieldContextValue; +} diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts index 3698808a00be..010b5eda898d 100644 --- a/packages/x-date-pickers/src/internals/index.ts +++ b/packages/x-date-pickers/src/internals/index.ts @@ -4,8 +4,7 @@ export type { PickersArrowSwitcherSlots, PickersArrowSwitcherSlotProps, } from './components/PickersArrowSwitcher'; -export { PickersProvider as PickersFieldProvider } from './components/PickersProvider'; -export type { PickersFieldContextValue } from './components/PickersProvider'; +export { PickersProvider } from './components/PickersProvider'; export { PickersModalDialog } from './components/PickersModalDialog'; export type { PickersModalDialogSlots, From 1f185cf781501c6979ed0f959a5e4bac9e325138 Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 12:38:39 +0200 Subject: [PATCH 16/33] Improve typing --- .../ReadonlyMaterialTextField.js | 1 - .../ReadonlyMaterialTextField.tsx | 9 ++-- .../experimentation/CustomField.js | 47 ------------------ .../experimentation/CustomField.tsx | 48 ------------------- .../experimentation/CustomField.tsx.preview | 6 --- .../experimentation/experimentation.md | 4 -- .../src/DateField/DateField.types.ts | 16 +------ .../x-date-pickers/src/DateField/index.ts | 1 - .../src/DatePicker/DatePicker.types.ts | 22 ++++++++- .../x-date-pickers/src/DatePicker/index.ts | 7 ++- .../src/DateTimeField/DateTimeField.types.ts | 20 +------- .../x-date-pickers/src/DateTimeField/index.ts | 1 - .../DateTimePicker/DateTimePicker.types.ts | 27 ++++++++++- .../src/DateTimePicker/index.ts | 1 + .../src/TimeField/TimeField.types.ts | 16 +------ .../x-date-pickers/src/TimeField/index.ts | 1 - .../src/TimePicker/TimePicker.types.ts | 23 ++++++++- .../x-date-pickers/src/TimePicker/index.ts | 7 ++- .../src/hooks/usePickersFieldContext.ts | 1 + scripts/x-date-pickers-pro.exports.json | 6 +-- scripts/x-date-pickers.exports.json | 6 +-- 21 files changed, 98 insertions(+), 172 deletions(-) delete mode 100644 docs/data/date-pickers/experimentation/CustomField.js delete mode 100644 docs/data/date-pickers/experimentation/CustomField.tsx delete mode 100644 docs/data/date-pickers/experimentation/CustomField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js index 7ca1f137f3b1..928444ed250c 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js @@ -4,7 +4,6 @@ import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; - import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx index 3cb0ee7f002d..d235acaa0ccb 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx @@ -3,8 +3,11 @@ import { Dayjs } from 'dayjs'; import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker, DatePickerProps } from '@mui/x-date-pickers/DatePicker'; -import { DateFieldInPickerProps } from '@mui/x-date-pickers/DateField'; +import { + DatePicker, + DatePickerProps, + DatePickerFieldProps, +} from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, @@ -12,7 +15,7 @@ import { usePickersFieldContext, } from '@mui/x-date-pickers/hooks'; -function ReadonlyDateField(props: DateFieldInPickerProps) { +function ReadonlyDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; diff --git a/docs/data/date-pickers/experimentation/CustomField.js b/docs/data/date-pickers/experimentation/CustomField.js deleted file mode 100644 index 3a093244e39a..000000000000 --- a/docs/data/date-pickers/experimentation/CustomField.js +++ /dev/null @@ -1,47 +0,0 @@ -import * as React from 'react'; -import dayjs from 'dayjs'; -import TextField from '@mui/material/TextField'; -import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; -import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; - -function ReadOnlyField(props) { - const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - - const { value, timezone, format } = internalProps; - const { InputProps, slotProps, slots, ...other } = forwardedProps; - - const { hasValidationError } = useValidation({ - validator: validateDate, - value, - timezone, - props: internalProps, - }); - - return ( - - ); -} - -export default function CustomField() { - return ( - - - - - - ); -} diff --git a/docs/data/date-pickers/experimentation/CustomField.tsx b/docs/data/date-pickers/experimentation/CustomField.tsx deleted file mode 100644 index ddacbf62d264..000000000000 --- a/docs/data/date-pickers/experimentation/CustomField.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import * as React from 'react'; -import dayjs, { Dayjs } from 'dayjs'; -import TextField from '@mui/material/TextField'; -import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; -import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; -import { DateFieldInPickerProps } from '@mui/x-date-pickers/DateField'; - -function ReadOnlyField(props: DateFieldInPickerProps) { - const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - - const { value, timezone, format } = internalProps; - const { InputProps, slotProps, slots, ...other } = forwardedProps; - - const { hasValidationError } = useValidation({ - validator: validateDate, - value, - timezone, - props: internalProps, - }); - - return ( - - ); -} - -export default function CustomField() { - return ( - - - - - - ); -} diff --git a/docs/data/date-pickers/experimentation/CustomField.tsx.preview b/docs/data/date-pickers/experimentation/CustomField.tsx.preview deleted file mode 100644 index b489d70b2175..000000000000 --- a/docs/data/date-pickers/experimentation/CustomField.tsx.preview +++ /dev/null @@ -1,6 +0,0 @@ - \ No newline at end of file diff --git a/docs/data/date-pickers/experimentation/experimentation.md b/docs/data/date-pickers/experimentation/experimentation.md index d5f906e32868..88b3ea3fe5ad 100644 --- a/docs/data/date-pickers/experimentation/experimentation.md +++ b/docs/data/date-pickers/experimentation/experimentation.md @@ -5,7 +5,3 @@ productId: x-date-pickers # Date and Time Pickers experimentation

Demos not accessible through the navbar of the doc

- -## Custom field - -{{"demo": "CustomField.js"}} diff --git a/packages/x-date-pickers/src/DateField/DateField.types.ts b/packages/x-date-pickers/src/DateField/DateField.types.ts index 57ab1e1830ae..cf1bdfcc800a 100644 --- a/packages/x-date-pickers/src/DateField/DateField.types.ts +++ b/packages/x-date-pickers/src/DateField/DateField.types.ts @@ -11,10 +11,9 @@ import { FieldSection, PickerValidDate, BuiltInFieldTextFieldProps, - BaseSingleInputFieldProps, } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; -import { MakeOptional, DefaultizedProps } from '../internals/models/helpers'; +import { MakeOptional } from '../internals/models/helpers'; import { BaseDateValidationProps, DayValidationProps, @@ -41,19 +40,6 @@ export interface UseDateFieldProps< BaseDateValidationProps, ExportedUseClearableFieldProps {} -/** - * Props the field can receive when used inside a date picker. - * (`DatePicker`, `DesktopDatePicker` or `MobileDatePicker` component). - */ -export type DateFieldInPickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> = DefaultizedProps< - UseDateFieldProps, - 'format' | 'timezone' | keyof BaseDateValidationProps -> & - BaseSingleInputFieldProps; - export type UseDateFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/DateField/index.ts b/packages/x-date-pickers/src/DateField/index.ts index e5f8fe21dcb2..cd6119e98a25 100644 --- a/packages/x-date-pickers/src/DateField/index.ts +++ b/packages/x-date-pickers/src/DateField/index.ts @@ -4,5 +4,4 @@ export type { UseDateFieldProps, UseDateFieldComponentProps, DateFieldProps, - DateFieldInPickerProps, } from './DateField.types'; diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts index be4f6c1fbfca..26d759a73fca 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts @@ -1,14 +1,22 @@ +import { UseDateFieldProps } from '../DateField'; import { DesktopDatePickerProps, DesktopDatePickerSlots, DesktopDatePickerSlotProps, } from '../DesktopDatePicker'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseDateValidationProps } from '../internals/models/validation'; import { MobileDatePickerProps, MobileDatePickerSlots, MobileDatePickerSlotProps, } from '../MobileDatePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + DateValidationError, + FieldSection, + PickerValidDate, +} from '../models'; export interface DatePickerSlots extends DesktopDatePickerSlots, @@ -47,3 +55,15 @@ export interface DatePickerProps< */ yearsPerRow?: 3 | 4; } + +/** + * Props the field can receive when used inside a `DatePicker`, `DesktopDatePicker` or `MobileDatePicker` component. + */ +export type DatePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, +> = DefaultizedProps< + UseDateFieldProps, + 'format' | 'timezone' | keyof BaseDateValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DatePicker/index.ts b/packages/x-date-pickers/src/DatePicker/index.ts index 8c1fecffe1aa..117b9833d3d2 100644 --- a/packages/x-date-pickers/src/DatePicker/index.ts +++ b/packages/x-date-pickers/src/DatePicker/index.ts @@ -1,5 +1,10 @@ export { DatePicker } from './DatePicker'; -export type { DatePickerProps, DatePickerSlots, DatePickerSlotProps } from './DatePicker.types'; +export type { + DatePickerProps, + DatePickerSlots, + DatePickerSlotProps, + DatePickerFieldProps, +} from './DatePicker.types'; export { DatePickerToolbar } from './DatePickerToolbar'; export type { DatePickerToolbarProps } from './DatePickerToolbar'; diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts index e19e41a6345a..625f70532e55 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts @@ -6,10 +6,9 @@ import { FieldSection, PickerValidDate, BuiltInFieldTextFieldProps, - BaseSingleInputFieldProps, } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; -import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; +import { MakeOptional } from '../internals/models/helpers'; import { BaseDateValidationProps, BaseTimeValidationProps, @@ -53,23 +52,6 @@ export interface UseDateTimeFieldProps< ampm?: boolean; } -/** - * Props the field can receive when used inside a date time picker. - * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component). - */ -export type DateTimeFieldInPickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> = DefaultizedProps< - UseDateTimeFieldProps, - | 'format' - | 'timezone' - | 'ampm' - | keyof BaseDateValidationProps - | keyof BaseTimeValidationProps -> & - BaseSingleInputFieldProps; - export type UseDateTimeFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/DateTimeField/index.ts b/packages/x-date-pickers/src/DateTimeField/index.ts index 212ce42432f5..95952dde9474 100644 --- a/packages/x-date-pickers/src/DateTimeField/index.ts +++ b/packages/x-date-pickers/src/DateTimeField/index.ts @@ -4,5 +4,4 @@ export type { UseDateTimeFieldProps, UseDateTimeFieldComponentProps, DateTimeFieldProps, - DateTimeFieldInPickerProps, } from './DateTimeField.types'; diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts index 8053bc8c5c63..ffa82991f541 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts @@ -1,15 +1,23 @@ +import { UseDateTimeFieldProps } from '../DateTimeField'; import { DesktopDateTimePickerProps, DesktopDateTimePickerSlots, DesktopDateTimePickerSlotProps, } from '../DesktopDateTimePicker'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseDateValidationProps, BaseTimeValidationProps } from '../internals/models/validation'; import { MobileDateTimePickerProps, MobileDateTimePickerSlots, MobileDateTimePickerSlotProps, } from '../MobileDateTimePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + DateTimeValidationError, + FieldSection, + PickerValidDate, +} from '../models'; import { ExportedYearCalendarProps } from '../YearCalendar/YearCalendar.types'; export interface DateTimePickerSlots @@ -61,3 +69,20 @@ export interface DateTimePickerProps< */ yearsPerRow?: 3 | 4; } + +/** + * Props the field can receive when used inside a date time picker. + * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component). + */ +export type DateTimePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, +> = DefaultizedProps< + UseDateTimeFieldProps, + | 'format' + | 'timezone' + | 'ampm' + | keyof BaseDateValidationProps + | keyof BaseTimeValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DateTimePicker/index.ts b/packages/x-date-pickers/src/DateTimePicker/index.ts index 06679b01c354..d6c805676912 100644 --- a/packages/x-date-pickers/src/DateTimePicker/index.ts +++ b/packages/x-date-pickers/src/DateTimePicker/index.ts @@ -3,6 +3,7 @@ export type { DateTimePickerProps, DateTimePickerSlots, DateTimePickerSlotProps, + DateTimePickerFieldProps, } from './DateTimePicker.types'; export { DateTimePickerTabs } from './DateTimePickerTabs'; diff --git a/packages/x-date-pickers/src/TimeField/TimeField.types.ts b/packages/x-date-pickers/src/TimeField/TimeField.types.ts index 0ce1a53d6e40..478cf08ee9ee 100644 --- a/packages/x-date-pickers/src/TimeField/TimeField.types.ts +++ b/packages/x-date-pickers/src/TimeField/TimeField.types.ts @@ -2,14 +2,13 @@ import * as React from 'react'; import { SlotComponentProps } from '@mui/utils'; import TextField from '@mui/material/TextField'; import { UseFieldInternalProps } from '../internals/hooks/useField'; -import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; +import { MakeOptional } from '../internals/models/helpers'; import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation'; import { FieldSection, PickerValidDate, TimeValidationError, BuiltInFieldTextFieldProps, - BaseSingleInputFieldProps, } from '../models'; import { ExportedUseClearableFieldProps, @@ -40,19 +39,6 @@ export interface UseTimeFieldProps< ampm?: boolean; } -/** - * Props the field can receive when used inside a time picker. - * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component). - */ -export type TimeFieldInPickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> = DefaultizedProps< - UseTimeFieldProps, - 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps -> & - BaseSingleInputFieldProps; - export type UseTimeFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/TimeField/index.ts b/packages/x-date-pickers/src/TimeField/index.ts index cf9c1e6a5881..f335f0f8fd76 100644 --- a/packages/x-date-pickers/src/TimeField/index.ts +++ b/packages/x-date-pickers/src/TimeField/index.ts @@ -4,5 +4,4 @@ export type { UseTimeFieldProps, UseTimeFieldComponentProps, TimeFieldProps, - TimeFieldInPickerProps, } from './TimeField.types'; diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts index 23121361eff6..d5cace991da6 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts @@ -4,12 +4,20 @@ import { DesktopTimePickerSlotProps, } from '../DesktopTimePicker'; import { TimeViewWithMeridiem } from '../internals/models'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseTimeValidationProps } from '../internals/models/validation'; import { MobileTimePickerProps, MobileTimePickerSlots, MobileTimePickerSlotProps, } from '../MobileTimePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + FieldSection, + PickerValidDate, + TimeValidationError, +} from '../models'; +import { UseTimeFieldProps } from '../TimeField'; export interface TimePickerSlots extends DesktopTimePickerSlots, @@ -46,3 +54,16 @@ export interface TimePickerProps< */ slotProps?: TimePickerSlotProps; } + +/** + * Props the field can receive when used inside a time picker. + * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component). + */ +export type TimePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean, +> = DefaultizedProps< + UseTimeFieldProps, + 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/TimePicker/index.ts b/packages/x-date-pickers/src/TimePicker/index.ts index 485198a142bf..9f2f67d1a536 100644 --- a/packages/x-date-pickers/src/TimePicker/index.ts +++ b/packages/x-date-pickers/src/TimePicker/index.ts @@ -1,5 +1,10 @@ export { TimePicker } from './TimePicker'; -export type { TimePickerProps, TimePickerSlots, TimePickerSlotProps } from './TimePicker.types'; +export type { + TimePickerProps, + TimePickerSlots, + TimePickerSlotProps, + TimePickerFieldProps, +} from './TimePicker.types'; export { TimePickerToolbar } from './TimePickerToolbar'; export type { TimePickerToolbarProps } from './TimePickerToolbar'; diff --git a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts index 7833d07f9094..51f92402681a 100644 --- a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts +++ b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts @@ -1,3 +1,4 @@ +'use client'; import * as React from 'react'; import { PickersFieldContext } from '../internals/components/PickersProvider'; diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 0833e97aea4e..c5daa5167924 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -34,10 +34,10 @@ { "name": "DateCalendarSlotProps", "kind": "Interface" }, { "name": "DateCalendarSlots", "kind": "Interface" }, { "name": "DateField", "kind": "Variable" }, - { "name": "DateFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateFieldProps", "kind": "TypeAlias" }, { "name": "DateOrTimeView", "kind": "TypeAlias" }, { "name": "DatePicker", "kind": "Variable" }, + { "name": "DatePickerFieldProps", "kind": "TypeAlias" }, { "name": "DatePickerProps", "kind": "Interface" }, { "name": "DatePickerSlotProps", "kind": "Interface" }, { "name": "DatePickerSlots", "kind": "Interface" }, @@ -72,9 +72,9 @@ { "name": "DateRangeValidationError", "kind": "TypeAlias" }, { "name": "DateRangeViewRendererProps", "kind": "Interface" }, { "name": "DateTimeField", "kind": "Variable" }, - { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateTimeFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePicker", "kind": "Variable" }, + { "name": "DateTimePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePickerProps", "kind": "Interface" }, { "name": "DateTimePickerSlotProps", "kind": "Interface" }, { "name": "DateTimePickerSlots", "kind": "Interface" }, @@ -372,10 +372,10 @@ { "name": "TimeClockSlotProps", "kind": "Interface" }, { "name": "TimeClockSlots", "kind": "Interface" }, { "name": "TimeField", "kind": "Variable" }, - { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "TimeFieldProps", "kind": "TypeAlias" }, { "name": "TimeIcon", "kind": "Variable" }, { "name": "TimePicker", "kind": "Variable" }, + { "name": "TimePickerFieldProps", "kind": "TypeAlias" }, { "name": "TimePickerProps", "kind": "Interface" }, { "name": "TimePickerSlotProps", "kind": "Interface" }, { "name": "TimePickerSlots", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index d77a6bf000fc..c0a5d40a0068 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -31,10 +31,10 @@ { "name": "DateCalendarSlotProps", "kind": "Interface" }, { "name": "DateCalendarSlots", "kind": "Interface" }, { "name": "DateField", "kind": "Variable" }, - { "name": "DateFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateFieldProps", "kind": "TypeAlias" }, { "name": "DateOrTimeView", "kind": "TypeAlias" }, { "name": "DatePicker", "kind": "Variable" }, + { "name": "DatePickerFieldProps", "kind": "TypeAlias" }, { "name": "DatePickerProps", "kind": "Interface" }, { "name": "DatePickerSlotProps", "kind": "Interface" }, { "name": "DatePickerSlots", "kind": "Interface" }, @@ -45,9 +45,9 @@ { "name": "DatePickerToolbarProps", "kind": "Interface" }, { "name": "DateRangeIcon", "kind": "Variable" }, { "name": "DateTimeField", "kind": "Variable" }, - { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateTimeFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePicker", "kind": "Variable" }, + { "name": "DateTimePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePickerProps", "kind": "Interface" }, { "name": "DateTimePickerSlotProps", "kind": "Interface" }, { "name": "DateTimePickerSlots", "kind": "Interface" }, @@ -271,10 +271,10 @@ { "name": "TimeClockSlotProps", "kind": "Interface" }, { "name": "TimeClockSlots", "kind": "Interface" }, { "name": "TimeField", "kind": "Variable" }, - { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "TimeFieldProps", "kind": "TypeAlias" }, { "name": "TimeIcon", "kind": "Variable" }, { "name": "TimePicker", "kind": "Variable" }, + { "name": "TimePickerFieldProps", "kind": "TypeAlias" }, { "name": "TimePickerProps", "kind": "Interface" }, { "name": "TimePickerSlotProps", "kind": "Interface" }, { "name": "TimePickerSlots", "kind": "Interface" }, From 5f7f8e5ca3345e5cf63b5da3e1725bdc51543bdf Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 24 Sep 2024 14:14:31 +0200 Subject: [PATCH 17/33] Work --- packages/x-date-pickers/src/DatePicker/DatePicker.types.ts | 2 +- .../x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts | 2 +- packages/x-date-pickers/src/TimePicker/TimePicker.types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts index 26d759a73fca..5a839bae4155 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts @@ -61,7 +61,7 @@ export interface DatePickerProps< */ export type DatePickerFieldProps< TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, + TEnableAccessibleFieldDOMStructure extends boolean = false, > = DefaultizedProps< UseDateFieldProps, 'format' | 'timezone' | keyof BaseDateValidationProps diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts index ffa82991f541..6ae28b8bc2fe 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts @@ -76,7 +76,7 @@ export interface DateTimePickerProps< */ export type DateTimePickerFieldProps< TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, + TEnableAccessibleFieldDOMStructure extends boolean = false, > = DefaultizedProps< UseDateTimeFieldProps, | 'format' diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts index d5cace991da6..ea7f4fd343b1 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts @@ -61,7 +61,7 @@ export interface TimePickerProps< */ export type TimePickerFieldProps< TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, + TEnableAccessibleFieldDOMStructure extends boolean = false, > = DefaultizedProps< UseTimeFieldProps, 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps From 7bd2d322bb1b7e87436755ef23e1108e6754463f Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 30 Sep 2024 11:14:51 +0200 Subject: [PATCH 18/33] Review Arthur --- ...ield.tsx => ReadOnlyMaterialTextField.tsx} | 10 ++-- .../ReadonlyMaterialTextField.js | 53 ------------------- .../ReadonlyMaterialTextField.tsx.preview | 1 - .../date-pickers/custom-field/custom-field.md | 6 +-- 4 files changed, 8 insertions(+), 62 deletions(-) rename docs/data/date-pickers/custom-field/custom-behavior/{ReadonlyMaterialTextField.tsx => ReadOnlyMaterialTextField.tsx} (83%) delete mode 100644 docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js delete mode 100644 docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx similarity index 83% rename from docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx rename to docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx index d235acaa0ccb..fd4f51ab13fe 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx @@ -15,7 +15,7 @@ import { usePickersFieldContext, } from '@mui/x-date-pickers/hooks'; -function ReadonlyDateField(props: DatePickerFieldProps) { +function ReadOnlyDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; @@ -42,16 +42,16 @@ function ReadonlyDateField(props: DatePickerFieldProps) { ); } -function ReadonlyFieldDatePicker(props: DatePickerProps) { +function ReadOnlyFieldDatePicker(props: DatePickerProps) { return ( - + ); } -export default function ReadonlyMaterialTextField() { +export default function ReadOnlyMaterialTextField() { return ( - + ); } diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js deleted file mode 100644 index 928444ed250c..000000000000 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.js +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; - -import TextField from '@mui/material/TextField'; -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; -import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; -import { - useSplitFieldProps, - useFieldPlaceholder, - usePickersFieldContext, -} from '@mui/x-date-pickers/hooks'; - -function ReadonlyDateField(props) { - const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); - const { value, timezone, format } = internalProps; - const { InputProps, slotProps, slots, ...other } = forwardedProps; - - const pickerContext = usePickersFieldContext(); - - const placeholder = useFieldPlaceholder(internalProps); - const { hasValidationError } = useValidation({ - validator: validateDate, - value, - timezone, - props: internalProps, - }); - - return ( - - ); -} - -function ReadonlyFieldDatePicker(props) { - return ( - - ); -} - -export default function ReadonlyMaterialTextField() { - return ( - - - - ); -} diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview deleted file mode 100644 index 5442e4084c47..000000000000 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadonlyMaterialTextField.tsx.preview +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/data/date-pickers/custom-field/custom-field.md b/docs/data/date-pickers/custom-field/custom-field.md index 162f11ebbaf6..4f5b5f782fb3 100644 --- a/docs/data/date-pickers/custom-field/custom-field.md +++ b/docs/data/date-pickers/custom-field/custom-field.md @@ -160,14 +160,14 @@ you can replace the field with an `Autocomplete` listing those dates: ### Using a read-only `TextField` -If you only want to allow the user to pick a value through the views, +If you want users to select a value exclusively through the views but you still want the UI to look like a `TextField`, you can replace the field with a read-only `TextField`: -{{"demo": "custom-behavior/ReadonlyMaterialTextField.js", "defaultCodeOpen": false}} +{{"demo": "custom-behavior/ReadOnlyMaterialTextField.js", "defaultCodeOpen": false}} ### Using a `Button` -If you only want to allow the user to pick a value through the views, +If you want users to select a value exclusively through the views and you don't want the UI to look like a `TextField`, you can replace the field with a `Button`: {{"demo": "PickerWithButtonField.js", "defaultCodeOpen": false}} From 299a96c42a68e7da7e72ad8da1a6bdcc36099219 Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 30 Sep 2024 12:17:08 +0200 Subject: [PATCH 19/33] Work --- .../ReadOnlyMaterialTextField.js | 53 +++++++++++++++++++ .../ReadOnlyMaterialTextField.tsx.preview | 1 + 2 files changed, 54 insertions(+) create mode 100644 docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js create mode 100644 docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx.preview diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js new file mode 100644 index 000000000000..b6e5537504c5 --- /dev/null +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -0,0 +1,53 @@ +import * as React from 'react'; + +import TextField from '@mui/material/TextField'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; +import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; +import { + useSplitFieldProps, + useFieldPlaceholder, + usePickersFieldContext, +} from '@mui/x-date-pickers/hooks'; + +function ReadOnlyDateField(props) { + const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); + const { value, timezone, format } = internalProps; + const { InputProps, slotProps, slots, ...other } = forwardedProps; + + const pickerContext = usePickersFieldContext(); + + const placeholder = useFieldPlaceholder(internalProps); + const { hasValidationError } = useValidation({ + validator: validateDate, + value, + timezone, + props: internalProps, + }); + + return ( + + ); +} + +function ReadOnlyFieldDatePicker(props) { + return ( + + ); +} + +export default function ReadOnlyMaterialTextField() { + return ( + + + + ); +} diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx.preview b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx.preview new file mode 100644 index 000000000000..e3842a12cb5d --- /dev/null +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx.preview @@ -0,0 +1 @@ + \ No newline at end of file From 164a1deb72f92d35a624e608cb4a5cd73eeac8bf Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 1 Oct 2024 13:51:33 +0200 Subject: [PATCH 20/33] Work --- .../custom-behavior/ReadOnlyMaterialTextField.js | 2 +- .../custom-behavior/ReadOnlyMaterialTextField.tsx | 2 +- .../src/internals/components/PickersProvider.tsx | 6 +++++- .../src/internals/hooks/usePicker/usePicker.ts | 9 +-------- .../internals/hooks/usePicker/usePicker.types.ts | 4 +--- .../internals/hooks/usePicker/usePickerValue.ts | 15 +++++++++++++++ .../hooks/usePicker/usePickerValue.types.ts | 2 ++ 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index b6e5537504c5..738926201cd2 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -33,7 +33,7 @@ function ReadOnlyDateField(props) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickerContext.onOpen} + onClick={pickerContext.onViewToggle} /> ); } diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx index fd4f51ab13fe..d8a48f7c0095 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx @@ -37,7 +37,7 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickerContext.onOpen} + onClick={pickerContext.onToggleView} /> ); } diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index 00cfddcd5500..8757e9830b63 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -31,5 +31,9 @@ interface PickersFieldProviderProps { } export interface PickersFieldContextValue { - onOpen: (event: React.UIEvent) => void; + /** + * Open the view if they are closed, close them otherwise. + * @param {React.UIEvent} event The DOM event that triggered the change. + */ + onToggleView: (event: React.UIEvent) => void; } 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 0f3f24c62760..5ae14ceb10b1 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -1,4 +1,3 @@ -import * as React from 'react'; import { warnOnce } from '@mui/x-internals/warning'; import { UsePickerParams, UsePickerProps, UsePickerResponse } from './usePicker.types'; import { usePickerValue } from './usePickerValue'; @@ -6,7 +5,6 @@ import { usePickerViews } from './usePickerViews'; import { usePickerLayoutProps } from './usePickerLayoutProps'; import { FieldSection, PickerValidDate, InferError } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { PickersFieldContextValue } from '../../components/PickersProvider'; export const usePicker = < TValue, @@ -73,11 +71,6 @@ export const usePicker = < propsFromPickerViews: pickerViewsResponse.layoutProps, }); - const fieldContextValue = React.useMemo( - () => ({ onOpen: pickerValueResponse.actions.onOpen }), - [pickerValueResponse.actions.onOpen], - ); - return { // Picker value open: pickerValueResponse.open, @@ -93,6 +86,6 @@ export const usePicker = < layoutProps: pickerLayoutResponse.layoutProps, // Picker field - fieldContextValue, + fieldContextValue: pickerValueResponse.fieldContextValue, }; }; 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 d428f89db05b..0bfee6af0b0d 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 @@ -65,6 +65,4 @@ export interface UsePickerResponse< TError, > extends Omit, 'viewProps' | 'layoutProps'>, Omit, 'layoutProps'>, - UsePickerLayoutPropsResponse { - fieldContextValue: PickersFieldContextValue; -} + UsePickerLayoutPropsResponse {} 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 8d6255b5f562..9d15af219dff 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -28,6 +28,7 @@ import { PickerValueUpdaterParams, } from './usePickerValue.types'; import { useValueWithTimezone } from '../useValueWithTimezone'; +import { PickersFieldContextValue } from '../../components/PickersProvider'; /** * Decide if the new value should be published @@ -457,11 +458,25 @@ export const usePickerValue = < isValid, }; + const fieldContextValue = React.useMemo( + () => ({ + onToggleView: (event) => { + if (isOpen) { + handleClose(event); + } else { + handleOpen(event); + } + }, + }), + [isOpen, handleClose, handleOpen], + ); + return { open: isOpen, fieldProps: fieldResponse, viewProps: viewResponse, layoutProps: layoutResponse, actions, + fieldContextValue, }; }; 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 a2882f62f57f..7b3b731ed105 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 @@ -17,6 +17,7 @@ import { PickerShortcutChangeImportance, PickersShortcutsItemContext, } from '../../../PickersShortcuts'; +import { PickersFieldContextValue } from '../../components/PickersProvider'; export interface PickerValueManager { /** @@ -327,4 +328,5 @@ export interface UsePickerValueResponse; fieldProps: UsePickerValueFieldResponse; layoutProps: UsePickerValueLayoutResponse; + fieldContextValue: PickersFieldContextValue; } From 7adf029a6ac42cc20db2481f756eb126c513fe3f Mon Sep 17 00:00:00 2001 From: flavien Date: Tue, 1 Oct 2024 14:07:50 +0200 Subject: [PATCH 21/33] Fix --- .../custom-field/custom-behavior/ReadOnlyMaterialTextField.js | 2 +- .../src/internals/hooks/usePicker/usePicker.types.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 738926201cd2..071100d224be 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -33,7 +33,7 @@ function ReadOnlyDateField(props) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickerContext.onViewToggle} + onClick={pickerContext.onToggleView} /> ); } 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 0bfee6af0b0d..21c6ec9ed51f 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 @@ -13,7 +13,6 @@ import { import { UsePickerLayoutProps, UsePickerLayoutPropsResponse } from './usePickerLayoutProps'; import { FieldSection, PickerValidDate } from '../../../models'; import { DateOrTimeViewWithMeridiem } from '../../models'; -import { PickersFieldContextValue } from '../../components/PickersProvider'; /** * Props common to all picker headless implementations. From 77ef2429d8414ddf96dc443bbdf58b8aeb2ba948 Mon Sep 17 00:00:00 2001 From: flavien Date: Fri, 4 Oct 2024 15:04:51 +0200 Subject: [PATCH 22/33] Review Lukas --- .../ReadOnlyMaterialTextField.js | 8 ++++---- .../ReadOnlyMaterialTextField.tsx | 8 ++++---- packages/x-date-pickers/src/hooks/index.tsx | 2 +- .../src/hooks/usePickersContext.ts | 19 +++++++++++++++++++ .../src/hooks/usePickersFieldContext.ts | 19 ------------------- .../internals/components/PickersProvider.tsx | 10 +++++----- .../hooks/usePicker/usePickerValue.ts | 4 ++-- .../hooks/usePicker/usePickerValue.types.ts | 4 ++-- scripts/x-date-pickers-pro.exports.json | 2 +- scripts/x-date-pickers.exports.json | 2 +- 10 files changed, 39 insertions(+), 39 deletions(-) create mode 100644 packages/x-date-pickers/src/hooks/usePickersContext.ts delete mode 100644 packages/x-date-pickers/src/hooks/usePickersFieldContext.ts diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 071100d224be..844d92176838 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -8,7 +8,7 @@ import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useFieldPlaceholder, - usePickersFieldContext, + usePickersContext, } from '@mui/x-date-pickers/hooks'; function ReadOnlyDateField(props) { @@ -16,7 +16,7 @@ function ReadOnlyDateField(props) { const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; - const pickerContext = usePickersFieldContext(); + const pickersContext = usePickersContext(); const placeholder = useFieldPlaceholder(internalProps); const { hasValidationError } = useValidation({ @@ -33,14 +33,14 @@ function ReadOnlyDateField(props) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickerContext.onToggleView} + onClick={pickersContext.onToggleView} /> ); } function ReadOnlyFieldDatePicker(props) { return ( - + ); } diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx index d8a48f7c0095..703ad2dae072 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx @@ -12,7 +12,7 @@ import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useFieldPlaceholder, - usePickersFieldContext, + usePickersContext, } from '@mui/x-date-pickers/hooks'; function ReadOnlyDateField(props: DatePickerFieldProps) { @@ -20,7 +20,7 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { const { value, timezone, format } = internalProps; const { InputProps, slotProps, slots, ...other } = forwardedProps; - const pickerContext = usePickersFieldContext(); + const pickersContext = usePickersContext(); const placeholder = useFieldPlaceholder(internalProps); const { hasValidationError } = useValidation({ @@ -37,14 +37,14 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { placeholder={placeholder} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickerContext.onToggleView} + onClick={pickersContext.onToggleView} /> ); } function ReadOnlyFieldDatePicker(props: DatePickerProps) { return ( - + ); } diff --git a/packages/x-date-pickers/src/hooks/index.tsx b/packages/x-date-pickers/src/hooks/index.tsx index 079dc26aa423..2f585bd801da 100644 --- a/packages/x-date-pickers/src/hooks/index.tsx +++ b/packages/x-date-pickers/src/hooks/index.tsx @@ -12,4 +12,4 @@ export { useSplitFieldProps } from './useSplitFieldProps'; export { useFieldPlaceholder } from './useFieldPlaceholder'; -export { usePickersFieldContext } from './usePickersFieldContext'; +export { usePickersContext } from './usePickersContext'; diff --git a/packages/x-date-pickers/src/hooks/usePickersContext.ts b/packages/x-date-pickers/src/hooks/usePickersContext.ts new file mode 100644 index 000000000000..9b6cc1c23e62 --- /dev/null +++ b/packages/x-date-pickers/src/hooks/usePickersContext.ts @@ -0,0 +1,19 @@ +'use client'; +import * as React from 'react'; +import { PickersContext } from '../internals/components/PickersProvider'; + +/** + * Returns the context passed by the picker the wraps the current component. + */ +export const usePickersContext = () => { + const value = React.useContext(PickersContext); + if (value == null) { + throw new Error( + [ + 'MUI X: The `usePickersContext` can only be called in fields that are used as a slot of a picker component', + ].join('\n'), + ); + } + + return value; +}; diff --git a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts b/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts deleted file mode 100644 index 51f92402681a..000000000000 --- a/packages/x-date-pickers/src/hooks/usePickersFieldContext.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use client'; -import * as React from 'react'; -import { PickersFieldContext } from '../internals/components/PickersProvider'; - -/** - * Returns the context passed by the picker that wraps the current field. - */ -export const usePickersFieldContext = () => { - const value = React.useContext(PickersFieldContext); - if (value == null) { - throw new Error( - [ - 'MUI X: The `usePickersFieldContext` can only be called in fields that are used as a slot of a picker component', - ].join('\n'), - ); - } - - return value; -}; diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index 8757e9830b63..9cdfbf83c790 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -3,7 +3,7 @@ import { PickerValidDate } from '../../models'; import { PickersInputLocaleText } from '../../locales'; import { LocalizationProvider } from '../../LocalizationProvider'; -export const PickersFieldContext = React.createContext(null); +export const PickersContext = React.createContext(null); /** * Provides the context for the various parts of a picker component: @@ -18,19 +18,19 @@ export function PickersProvider( const { fieldContextValue, localeText, children } = props; return ( - + {children} - + ); } interface PickersFieldProviderProps { - fieldContextValue: PickersFieldContextValue; + fieldContextValue: PickersContextValue; localeText: PickersInputLocaleText | undefined; children: React.ReactNode; } -export interface PickersFieldContextValue { +export interface PickersContextValue { /** * Open the view if they are closed, close them otherwise. * @param {React.UIEvent} event The DOM event that triggered the change. 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 9d15af219dff..e2a062f56d52 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -28,7 +28,7 @@ import { PickerValueUpdaterParams, } from './usePickerValue.types'; import { useValueWithTimezone } from '../useValueWithTimezone'; -import { PickersFieldContextValue } from '../../components/PickersProvider'; +import { PickersContextValue } from '../../components/PickersProvider'; /** * Decide if the new value should be published @@ -458,7 +458,7 @@ export const usePickerValue = < isValid, }; - const fieldContextValue = React.useMemo( + const fieldContextValue = React.useMemo( () => ({ onToggleView: (event) => { if (isOpen) { 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 7b3b731ed105..81ca78cfe872 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 @@ -17,7 +17,7 @@ import { PickerShortcutChangeImportance, PickersShortcutsItemContext, } from '../../../PickersShortcuts'; -import { PickersFieldContextValue } from '../../components/PickersProvider'; +import { PickersContextValue } from '../../components/PickersProvider'; export interface PickerValueManager { /** @@ -328,5 +328,5 @@ export interface UsePickerValueResponse; fieldProps: UsePickerValueFieldResponse; layoutProps: UsePickerValueLayoutResponse; - fieldContextValue: PickersFieldContextValue; + fieldContextValue: PickersContextValue; } diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index c5daa5167924..3901b785a96a 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -421,7 +421,7 @@ { "name": "UseMultiInputTimeRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputTimeRangeFieldProps", "kind": "Interface" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, - { "name": "usePickersFieldContext", "kind": "Variable" }, + { "name": "usePickersContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "UseSingleInputDateRangeFieldProps", "kind": "Interface" }, { "name": "UseSingleInputDateTimeRangeFieldProps", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index c0a5d40a0068..b2f7126714e4 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -306,7 +306,7 @@ { "name": "UseDateTimeFieldProps", "kind": "Interface" }, { "name": "useFieldPlaceholder", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, - { "name": "usePickersFieldContext", "kind": "Variable" }, + { "name": "usePickersContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, { "name": "useSplitFieldProps", "kind": "Variable" }, { "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" }, From a1bc87fd12966d6f20cfb10b19c9c643cdf5ca8c Mon Sep 17 00:00:00 2001 From: flavien Date: Fri, 4 Oct 2024 15:46:57 +0200 Subject: [PATCH 23/33] [pickers] Move the DateFieldInPickerProps interface to the picker folder and rename it DatePickerFieldProps (same for time and date time) --- .../src/DateField/DateField.types.ts | 16 +---------- .../x-date-pickers/src/DateField/index.ts | 1 - .../src/DatePicker/DatePicker.types.ts | 22 ++++++++++++++- .../x-date-pickers/src/DatePicker/index.ts | 7 ++++- .../src/DateTimeField/DateTimeField.types.ts | 20 +------------- .../x-date-pickers/src/DateTimeField/index.ts | 1 - .../DateTimePicker/DateTimePicker.types.ts | 27 ++++++++++++++++++- .../src/DateTimePicker/DateTimePickerTabs.tsx | 2 +- .../src/DateTimePicker/index.ts | 1 + .../src/TimeField/TimeField.types.ts | 16 +---------- .../x-date-pickers/src/TimeField/index.ts | 1 - .../src/TimePicker/TimePicker.types.ts | 23 +++++++++++++++- .../x-date-pickers/src/TimePicker/index.ts | 7 ++++- scripts/x-date-pickers-pro.exports.json | 6 ++--- scripts/x-date-pickers.exports.json | 6 ++--- 15 files changed, 92 insertions(+), 64 deletions(-) diff --git a/packages/x-date-pickers/src/DateField/DateField.types.ts b/packages/x-date-pickers/src/DateField/DateField.types.ts index 57ab1e1830ae..cf1bdfcc800a 100644 --- a/packages/x-date-pickers/src/DateField/DateField.types.ts +++ b/packages/x-date-pickers/src/DateField/DateField.types.ts @@ -11,10 +11,9 @@ import { FieldSection, PickerValidDate, BuiltInFieldTextFieldProps, - BaseSingleInputFieldProps, } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; -import { MakeOptional, DefaultizedProps } from '../internals/models/helpers'; +import { MakeOptional } from '../internals/models/helpers'; import { BaseDateValidationProps, DayValidationProps, @@ -41,19 +40,6 @@ export interface UseDateFieldProps< BaseDateValidationProps, ExportedUseClearableFieldProps {} -/** - * Props the field can receive when used inside a date picker. - * (`DatePicker`, `DesktopDatePicker` or `MobileDatePicker` component). - */ -export type DateFieldInPickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> = DefaultizedProps< - UseDateFieldProps, - 'format' | 'timezone' | keyof BaseDateValidationProps -> & - BaseSingleInputFieldProps; - export type UseDateFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/DateField/index.ts b/packages/x-date-pickers/src/DateField/index.ts index e5f8fe21dcb2..cd6119e98a25 100644 --- a/packages/x-date-pickers/src/DateField/index.ts +++ b/packages/x-date-pickers/src/DateField/index.ts @@ -4,5 +4,4 @@ export type { UseDateFieldProps, UseDateFieldComponentProps, DateFieldProps, - DateFieldInPickerProps, } from './DateField.types'; diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts index be4f6c1fbfca..5a839bae4155 100644 --- a/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts +++ b/packages/x-date-pickers/src/DatePicker/DatePicker.types.ts @@ -1,14 +1,22 @@ +import { UseDateFieldProps } from '../DateField'; import { DesktopDatePickerProps, DesktopDatePickerSlots, DesktopDatePickerSlotProps, } from '../DesktopDatePicker'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseDateValidationProps } from '../internals/models/validation'; import { MobileDatePickerProps, MobileDatePickerSlots, MobileDatePickerSlotProps, } from '../MobileDatePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + DateValidationError, + FieldSection, + PickerValidDate, +} from '../models'; export interface DatePickerSlots extends DesktopDatePickerSlots, @@ -47,3 +55,15 @@ export interface DatePickerProps< */ yearsPerRow?: 3 | 4; } + +/** + * Props the field can receive when used inside a `DatePicker`, `DesktopDatePicker` or `MobileDatePicker` component. + */ +export type DatePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean = false, +> = DefaultizedProps< + UseDateFieldProps, + 'format' | 'timezone' | keyof BaseDateValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DatePicker/index.ts b/packages/x-date-pickers/src/DatePicker/index.ts index 8c1fecffe1aa..117b9833d3d2 100644 --- a/packages/x-date-pickers/src/DatePicker/index.ts +++ b/packages/x-date-pickers/src/DatePicker/index.ts @@ -1,5 +1,10 @@ export { DatePicker } from './DatePicker'; -export type { DatePickerProps, DatePickerSlots, DatePickerSlotProps } from './DatePicker.types'; +export type { + DatePickerProps, + DatePickerSlots, + DatePickerSlotProps, + DatePickerFieldProps, +} from './DatePicker.types'; export { DatePickerToolbar } from './DatePickerToolbar'; export type { DatePickerToolbarProps } from './DatePickerToolbar'; diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts index e19e41a6345a..625f70532e55 100644 --- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts +++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts @@ -6,10 +6,9 @@ import { FieldSection, PickerValidDate, BuiltInFieldTextFieldProps, - BaseSingleInputFieldProps, } from '../models'; import { UseFieldInternalProps } from '../internals/hooks/useField'; -import { DefaultizedProps, MakeOptional } from '../internals/models/helpers'; +import { MakeOptional } from '../internals/models/helpers'; import { BaseDateValidationProps, BaseTimeValidationProps, @@ -53,23 +52,6 @@ export interface UseDateTimeFieldProps< ampm?: boolean; } -/** - * Props the field can receive when used inside a date time picker. - * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component). - */ -export type DateTimeFieldInPickerProps< - TDate extends PickerValidDate, - TEnableAccessibleFieldDOMStructure extends boolean, -> = DefaultizedProps< - UseDateTimeFieldProps, - | 'format' - | 'timezone' - | 'ampm' - | keyof BaseDateValidationProps - | keyof BaseTimeValidationProps -> & - BaseSingleInputFieldProps; - export type UseDateTimeFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/DateTimeField/index.ts b/packages/x-date-pickers/src/DateTimeField/index.ts index 212ce42432f5..95952dde9474 100644 --- a/packages/x-date-pickers/src/DateTimeField/index.ts +++ b/packages/x-date-pickers/src/DateTimeField/index.ts @@ -4,5 +4,4 @@ export type { UseDateTimeFieldProps, UseDateTimeFieldComponentProps, DateTimeFieldProps, - DateTimeFieldInPickerProps, } from './DateTimeField.types'; diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts index 8053bc8c5c63..6ae28b8bc2fe 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.types.ts @@ -1,15 +1,23 @@ +import { UseDateTimeFieldProps } from '../DateTimeField'; import { DesktopDateTimePickerProps, DesktopDateTimePickerSlots, DesktopDateTimePickerSlotProps, } from '../DesktopDateTimePicker'; import { DateOrTimeViewWithMeridiem } from '../internals/models'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseDateValidationProps, BaseTimeValidationProps } from '../internals/models/validation'; import { MobileDateTimePickerProps, MobileDateTimePickerSlots, MobileDateTimePickerSlotProps, } from '../MobileDateTimePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + DateTimeValidationError, + FieldSection, + PickerValidDate, +} from '../models'; import { ExportedYearCalendarProps } from '../YearCalendar/YearCalendar.types'; export interface DateTimePickerSlots @@ -61,3 +69,20 @@ export interface DateTimePickerProps< */ yearsPerRow?: 3 | 4; } + +/** + * Props the field can receive when used inside a date time picker. + * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component). + */ +export type DateTimePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean = false, +> = DefaultizedProps< + UseDateTimeFieldProps, + | 'format' + | 'timezone' + | 'ampm' + | keyof BaseDateValidationProps + | keyof BaseTimeValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx index dba5be6d3383..a9042194162d 100644 --- a/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx +++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx @@ -126,7 +126,7 @@ const DateTimePickerTabs = function DateTimePickerTabs = DefaultizedProps< - UseTimeFieldProps, - 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps -> & - BaseSingleInputFieldProps; - export type UseTimeFieldComponentProps< TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean, diff --git a/packages/x-date-pickers/src/TimeField/index.ts b/packages/x-date-pickers/src/TimeField/index.ts index cf9c1e6a5881..f335f0f8fd76 100644 --- a/packages/x-date-pickers/src/TimeField/index.ts +++ b/packages/x-date-pickers/src/TimeField/index.ts @@ -4,5 +4,4 @@ export type { UseTimeFieldProps, UseTimeFieldComponentProps, TimeFieldProps, - TimeFieldInPickerProps, } from './TimeField.types'; diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts index 23121361eff6..ea7f4fd343b1 100644 --- a/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts +++ b/packages/x-date-pickers/src/TimePicker/TimePicker.types.ts @@ -4,12 +4,20 @@ import { DesktopTimePickerSlotProps, } from '../DesktopTimePicker'; import { TimeViewWithMeridiem } from '../internals/models'; +import { DefaultizedProps } from '../internals/models/helpers'; +import { BaseTimeValidationProps } from '../internals/models/validation'; import { MobileTimePickerProps, MobileTimePickerSlots, MobileTimePickerSlotProps, } from '../MobileTimePicker'; -import { PickerValidDate } from '../models'; +import { + BaseSingleInputFieldProps, + FieldSection, + PickerValidDate, + TimeValidationError, +} from '../models'; +import { UseTimeFieldProps } from '../TimeField'; export interface TimePickerSlots extends DesktopTimePickerSlots, @@ -46,3 +54,16 @@ export interface TimePickerProps< */ slotProps?: TimePickerSlotProps; } + +/** + * Props the field can receive when used inside a time picker. + * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component). + */ +export type TimePickerFieldProps< + TDate extends PickerValidDate, + TEnableAccessibleFieldDOMStructure extends boolean = false, +> = DefaultizedProps< + UseTimeFieldProps, + 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps +> & + BaseSingleInputFieldProps; diff --git a/packages/x-date-pickers/src/TimePicker/index.ts b/packages/x-date-pickers/src/TimePicker/index.ts index 485198a142bf..9f2f67d1a536 100644 --- a/packages/x-date-pickers/src/TimePicker/index.ts +++ b/packages/x-date-pickers/src/TimePicker/index.ts @@ -1,5 +1,10 @@ export { TimePicker } from './TimePicker'; -export type { TimePickerProps, TimePickerSlots, TimePickerSlotProps } from './TimePicker.types'; +export type { + TimePickerProps, + TimePickerSlots, + TimePickerSlotProps, + TimePickerFieldProps, +} from './TimePicker.types'; export { TimePickerToolbar } from './TimePickerToolbar'; export type { TimePickerToolbarProps } from './TimePickerToolbar'; diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 24beed350813..efd9594f7858 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -34,10 +34,10 @@ { "name": "DateCalendarSlotProps", "kind": "Interface" }, { "name": "DateCalendarSlots", "kind": "Interface" }, { "name": "DateField", "kind": "Variable" }, - { "name": "DateFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateFieldProps", "kind": "TypeAlias" }, { "name": "DateOrTimeView", "kind": "TypeAlias" }, { "name": "DatePicker", "kind": "Variable" }, + { "name": "DatePickerFieldProps", "kind": "TypeAlias" }, { "name": "DatePickerProps", "kind": "Interface" }, { "name": "DatePickerSlotProps", "kind": "Interface" }, { "name": "DatePickerSlots", "kind": "Interface" }, @@ -72,9 +72,9 @@ { "name": "DateRangeValidationError", "kind": "TypeAlias" }, { "name": "DateRangeViewRendererProps", "kind": "Interface" }, { "name": "DateTimeField", "kind": "Variable" }, - { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateTimeFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePicker", "kind": "Variable" }, + { "name": "DateTimePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePickerProps", "kind": "Interface" }, { "name": "DateTimePickerSlotProps", "kind": "Interface" }, { "name": "DateTimePickerSlots", "kind": "Interface" }, @@ -372,10 +372,10 @@ { "name": "TimeClockSlotProps", "kind": "Interface" }, { "name": "TimeClockSlots", "kind": "Interface" }, { "name": "TimeField", "kind": "Variable" }, - { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "TimeFieldProps", "kind": "TypeAlias" }, { "name": "TimeIcon", "kind": "Variable" }, { "name": "TimePicker", "kind": "Variable" }, + { "name": "TimePickerFieldProps", "kind": "TypeAlias" }, { "name": "TimePickerProps", "kind": "Interface" }, { "name": "TimePickerSlotProps", "kind": "Interface" }, { "name": "TimePickerSlots", "kind": "Interface" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index 4ae16b168cba..8581ad347351 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -31,10 +31,10 @@ { "name": "DateCalendarSlotProps", "kind": "Interface" }, { "name": "DateCalendarSlots", "kind": "Interface" }, { "name": "DateField", "kind": "Variable" }, - { "name": "DateFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateFieldProps", "kind": "TypeAlias" }, { "name": "DateOrTimeView", "kind": "TypeAlias" }, { "name": "DatePicker", "kind": "Variable" }, + { "name": "DatePickerFieldProps", "kind": "TypeAlias" }, { "name": "DatePickerProps", "kind": "Interface" }, { "name": "DatePickerSlotProps", "kind": "Interface" }, { "name": "DatePickerSlots", "kind": "Interface" }, @@ -45,9 +45,9 @@ { "name": "DatePickerToolbarProps", "kind": "Interface" }, { "name": "DateRangeIcon", "kind": "Variable" }, { "name": "DateTimeField", "kind": "Variable" }, - { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "DateTimeFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePicker", "kind": "Variable" }, + { "name": "DateTimePickerFieldProps", "kind": "TypeAlias" }, { "name": "DateTimePickerProps", "kind": "Interface" }, { "name": "DateTimePickerSlotProps", "kind": "Interface" }, { "name": "DateTimePickerSlots", "kind": "Interface" }, @@ -271,10 +271,10 @@ { "name": "TimeClockSlotProps", "kind": "Interface" }, { "name": "TimeClockSlots", "kind": "Interface" }, { "name": "TimeField", "kind": "Variable" }, - { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" }, { "name": "TimeFieldProps", "kind": "TypeAlias" }, { "name": "TimeIcon", "kind": "Variable" }, { "name": "TimePicker", "kind": "Variable" }, + { "name": "TimePickerFieldProps", "kind": "TypeAlias" }, { "name": "TimePickerProps", "kind": "Interface" }, { "name": "TimePickerSlotProps", "kind": "Interface" }, { "name": "TimePickerSlots", "kind": "Interface" }, From 3642e3cb8f532e1f4a4fa115b4d857bcfdef7608 Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 7 Oct 2024 07:47:22 +0200 Subject: [PATCH 24/33] Fix --- docs/data/date-pickers/experimentation/CustomField.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/data/date-pickers/experimentation/CustomField.tsx b/docs/data/date-pickers/experimentation/CustomField.tsx index ddacbf62d264..b1c10ad6b095 100644 --- a/docs/data/date-pickers/experimentation/CustomField.tsx +++ b/docs/data/date-pickers/experimentation/CustomField.tsx @@ -4,12 +4,11 @@ import TextField from '@mui/material/TextField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; -import { DatePicker } from '@mui/x-date-pickers/DatePicker'; +import { DatePicker, DatePickerFieldProps } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps } from '@mui/x-date-pickers/hooks'; -import { DateFieldInPickerProps } from '@mui/x-date-pickers/DateField'; -function ReadOnlyField(props: DateFieldInPickerProps) { +function ReadOnlyField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { value, timezone, format } = internalProps; From 07a028577f253e92b1bd54cc4684510c27d42500 Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 7 Oct 2024 11:33:10 +0200 Subject: [PATCH 25/33] Review Lukas + JSDoc for useParsedFormat --- .../ReadOnlyMaterialTextField.js | 6 +- .../ReadOnlyMaterialTextField.tsx | 6 +- .../useDesktopRangePicker.tsx | 4 +- .../useMobileRangePicker.tsx | 4 +- packages/x-date-pickers/src/hooks/index.tsx | 2 +- .../src/hooks/useFieldPlaceholder.ts | 56 ----------------- .../src/hooks/useParsedFormat.ts | 61 +++++++++++++++++++ .../internals/components/PickersProvider.tsx | 8 +-- .../useDesktopPicker/useDesktopPicker.tsx | 4 +- .../hooks/useField/buildSectionsFromFormat.ts | 10 +-- .../hooks/useField/useField.utils.ts | 23 +++---- .../useField/useFieldCharacterEditing.ts | 3 +- .../internals/hooks/useField/useFieldState.ts | 6 +- .../hooks/useMobilePicker/useMobilePicker.tsx | 4 +- .../internals/hooks/usePicker/usePicker.ts | 2 +- .../hooks/usePicker/usePickerValue.ts | 4 +- .../hooks/usePicker/usePickerValue.types.ts | 2 +- scripts/x-date-pickers-pro.exports.json | 2 +- scripts/x-date-pickers.exports.json | 2 +- 19 files changed, 100 insertions(+), 109 deletions(-) delete mode 100644 packages/x-date-pickers/src/hooks/useFieldPlaceholder.ts create mode 100644 packages/x-date-pickers/src/hooks/useParsedFormat.ts diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 844d92176838..35d02256eea5 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -7,7 +7,7 @@ import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, - useFieldPlaceholder, + useParsedFormat, usePickersContext, } from '@mui/x-date-pickers/hooks'; @@ -18,7 +18,7 @@ function ReadOnlyDateField(props) { const pickersContext = usePickersContext(); - const placeholder = useFieldPlaceholder(internalProps); + const parsedFormat = useParsedFormat(internalProps); const { hasValidationError } = useValidation({ validator: validateDate, value, @@ -30,7 +30,7 @@ function ReadOnlyDateField(props) { ) { const pickersContext = usePickersContext(); - const placeholder = useFieldPlaceholder(internalProps); + const parsedFormat = useParsedFormat(internalProps); const { hasValidationError } = useValidation({ validator: validateDate, value, @@ -34,7 +34,7 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { , TDate, @@ -210,7 +210,7 @@ export const useDesktopRangePicker = < const Layout = slots?.layout ?? PickersLayout; const renderPicker = () => ( - + , TDate, @@ -215,7 +215,7 @@ export const useMobileRangePicker = < }; const renderPicker = () => ( - + ({ - format, - formatDensity = 'dense', - timezone, - shouldRespectLeadingZeros = false, -}: UseFieldPlaceholderParams) => { - const utils = useUtils(); - const isRtl = useRtl(); - const translations = usePickersTranslations(); - const localizedDigits = React.useMemo(() => getLocalizedDigits(utils), [utils]); - - return React.useMemo(() => { - const sections = buildSectionsFromFormat({ - utils, - format, - formatDensity, - isRtl, - timezone, - shouldRespectLeadingZeros, - localeText: translations, - localizedDigits, - date: null, - // TODO v9: Make sure we still don't reverse in `buildSectionsFromFormat` when using `useFieldPlaceholder`. - enableAccessibleFieldDOMStructure: false, - }); - - return sections - .map((section) => `${section.startSeparator}${section.placeholder}${section.endSeparator}`) - .join(''); - }, [ - utils, - isRtl, - translations, - localizedDigits, - format, - formatDensity, - timezone, - shouldRespectLeadingZeros, - ]); -}; diff --git a/packages/x-date-pickers/src/hooks/useParsedFormat.ts b/packages/x-date-pickers/src/hooks/useParsedFormat.ts new file mode 100644 index 000000000000..579356224ebe --- /dev/null +++ b/packages/x-date-pickers/src/hooks/useParsedFormat.ts @@ -0,0 +1,61 @@ +'use client'; +import * as React from 'react'; +import { useRtl } from '@mui/system/RtlProvider'; +import { useUtils } from '../internals/hooks/useUtils'; +import { buildSectionsFromFormat } from '../internals/hooks/useField/buildSectionsFromFormat'; +import { getLocalizedDigits } from '../internals/hooks/useField/useField.utils'; +import { PickerValidDate } from '../models'; +import { usePickersTranslations } from './usePickersTranslations'; +import type { UseFieldInternalProps } from '../internals/hooks/useField'; + +interface UseParsedFormatParameters + extends Pick< + UseFieldInternalProps, + 'format' | 'formatDensity' | 'shouldRespectLeadingZeros' + > {} + +/** + * Returns the parsed format to be rendered in the field when their is no value or in other parts of the picker. + * This format is localized (e.g: `AAAA` for the year with the French locale) and cannot be parsed by your date library. + * @param {object} The parameters needed to build the placeholder. + * @param {string} params.format Format of the date to use. + * @param {'dense' | 'spacious'} params.formatDensity Density of the format (setting `formatDensity` to `"spacious"` will add a space before and after each `/`, `-` and `.` character). + * @param {boolean} params.shouldRespectLeadingZeros If `true`, the format will respect the leading zeroes, if `false`, the format will always add leading zeroes. + * @returns + */ +export const useParsedFormat = ( + parameters: UseParsedFormatParameters, +) => { + const { format, formatDensity = 'dense', shouldRespectLeadingZeros = false } = parameters; + const utils = useUtils(); + const isRtl = useRtl(); + const translations = usePickersTranslations(); + const localizedDigits = React.useMemo(() => getLocalizedDigits(utils), [utils]); + + return React.useMemo(() => { + const sections = buildSectionsFromFormat({ + utils, + format, + formatDensity, + isRtl, + shouldRespectLeadingZeros, + localeText: translations, + localizedDigits, + date: null, + // TODO v9: Make sure we still don't reverse in `buildSectionsFromFormat` when using `useParsedFormat`. + enableAccessibleFieldDOMStructure: false, + }); + + return sections + .map((section) => `${section.startSeparator}${section.placeholder}${section.endSeparator}`) + .join(''); + }, [ + utils, + isRtl, + translations, + localizedDigits, + format, + formatDensity, + shouldRespectLeadingZeros, + ]); +}; diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index 9cdfbf83c790..faeea0b8da85 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -7,7 +7,7 @@ export const PickersContext = React.createContext(nu /** * Provides the context for the various parts of a picker component: - * - fieldContextValue: the context for the field + * - contextValue: the context for the picker sub-components. * - localizationProvider: the translations passed through the props and through a parent LocalizationProvider. * * @ignore - do not document. @@ -15,17 +15,17 @@ export const PickersContext = React.createContext(nu export function PickersProvider( props: PickersFieldProviderProps, ) { - const { fieldContextValue, localeText, children } = props; + const { contextValue, localeText, children } = props; return ( - + {children} ); } interface PickersFieldProviderProps { - fieldContextValue: PickersContextValue; + contextValue: PickersContextValue; localeText: PickersInputLocaleText | undefined; children: React.ReactNode; } 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 62897088a791..bd77cbc4d0e9 100644 --- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx @@ -80,7 +80,7 @@ export const useDesktopPicker = < renderCurrentView, shouldRestoreFocus, fieldProps: pickerFieldProps, - fieldContextValue, + contextValue, } = usePicker({ ...pickerParams, props, @@ -213,7 +213,7 @@ export const useDesktopPicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); const renderPicker = () => ( - + { format: string; formatDensity: 'dense' | 'spacious'; isRtl: boolean; - timezone: PickersTimezone; shouldRespectLeadingZeros: boolean; localeText: PickersLocaleText; localizedDigits: string[]; @@ -64,7 +63,6 @@ const getEscapedPartsFromFormat = ({ const getSectionPlaceholder = ( utils: MuiPickersAdapter, - timezone: PickersTimezone, localeText: PickersLocaleText, sectionConfig: Pick, sectionFormat: string, @@ -72,7 +70,7 @@ const getSectionPlaceholder = ( switch (sectionConfig.type) { case 'year': { return localeText.fieldYearPlaceholder({ - digitAmount: utils.formatByString(utils.date(undefined, timezone), sectionFormat).length, + digitAmount: utils.formatByString(utils.date(undefined, 'default'), sectionFormat).length, format: sectionFormat, }); } @@ -119,7 +117,6 @@ const getSectionPlaceholder = ( const createSection = ({ utils, - timezone, date, shouldRespectLeadingZeros, localeText, @@ -140,7 +137,6 @@ const createSection = ({ const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros( utils, - timezone, sectionConfig.contentType, sectionConfig.type, token, @@ -181,7 +177,7 @@ const createSection = ({ format: token, maxLength, value: sectionValue, - placeholder: getSectionPlaceholder(utils, timezone, localeText, sectionConfig, token), + placeholder: getSectionPlaceholder(utils, localeText, sectionConfig, token), hasLeadingZerosInFormat, hasLeadingZerosInInput, startSeparator, 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 71b5465dce55..e56f7029886f 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 @@ -65,12 +65,11 @@ const getDeltaFromKeyCode = (keyCode: Omit( utils: MuiPickersAdapter, - timezone: PickersTimezone, format: string, ) => { const elements: TDate[] = []; - const now = utils.date(undefined, timezone); + const now = utils.date(undefined, 'default'); const startDate = utils.startOfWeek(now); const endDate = utils.endOfWeek(now); @@ -97,7 +96,7 @@ export const getLetterEditingOptions = ( } case 'weekDay': { - return getDaysInWeekStr(utils, timezone, format); + return getDaysInWeekStr(utils, format); } case 'meridiem': { @@ -393,13 +392,11 @@ export const changeSectionValueFormat = ( const isFourDigitYearFormat = ( utils: MuiPickersAdapter, - timezone: PickersTimezone, format: string, -) => utils.formatByString(utils.date(undefined, timezone), format).length === 4; +) => utils.formatByString(utils.date(undefined, 'system'), format).length === 4; export const doesSectionFormatHaveLeadingZeros = ( utils: MuiPickersAdapter, - timezone: PickersTimezone, contentType: FieldSectionContentType, sectionType: FieldSectionType, format: string, @@ -408,12 +405,12 @@ export const doesSectionFormatHaveLeadingZeros = return false; } - const now = utils.date(undefined, timezone); + const now = utils.date(undefined, 'default'); switch (sectionType) { // We can't use `changeSectionValueFormat`, because `utils.parse('1', 'YYYY')` returns `1971` instead of `1`. case 'year': { - if (isFourDigitYearFormat(utils, timezone, format)) { + if (isFourDigitYearFormat(utils, format)) { const formatted0001 = utils.formatByString(utils.setYear(now, 1), format); return formatted0001 === '0001'; } @@ -547,7 +544,7 @@ export const getSectionsBoundaries = ( return { year: ({ format }) => ({ minimum: 0, - maximum: isFourDigitYearFormat(utils, timezone, format) ? 9999 : 99, + maximum: isFourDigitYearFormat(utils, format) ? 9999 : 99, }), month: () => ({ minimum: 1, @@ -564,7 +561,7 @@ export const getSectionsBoundaries = ( }), weekDay: ({ format, contentType }) => { if (contentType === 'digit') { - const daysInWeek = getDaysInWeekStr(utils, timezone, format).map(Number); + const daysInWeek = getDaysInWeekStr(utils, format).map(Number); return { minimum: Math.min(...daysInWeek), maximum: Math.max(...daysInWeek), @@ -653,7 +650,6 @@ export const validateSections = ( const transferDateSectionValue = ( utils: MuiPickersAdapter, - timezone: PickersTimezone, section: FieldSection, dateToTransferFrom: TDate, dateToTransferTo: TDate, @@ -668,7 +664,7 @@ const transferDateSectionValue = ( } case 'weekDay': { - const formattedDaysInWeek = getDaysInWeekStr(utils, timezone, section.format); + const formattedDaysInWeek = getDaysInWeekStr(utils, section.format); const dayInWeekStrOfActiveDate = utils.formatByString(dateToTransferFrom, section.format); const dayInWeekOfActiveDate = formattedDaysInWeek.indexOf(dayInWeekStrOfActiveDate); const dayInWeekOfNewSectionValue = formattedDaysInWeek.indexOf(section.value); @@ -728,7 +724,6 @@ const reliableSectionModificationOrder: Record = { export const mergeDateIntoReferenceDate = ( utils: MuiPickersAdapter, - timezone: PickersTimezone, dateToTransferFrom: TDate, sections: FieldSection[], referenceDate: TDate, @@ -741,7 +736,7 @@ export const mergeDateIntoReferenceDate = ( ) .reduce((mergedDate, section) => { if (!shouldLimitToEditedSections || section.modified) { - return transferDateSectionValue(utils, timezone, section, dateToTransferFrom, mergedDate); + return transferDateSectionValue(utils, section, dateToTransferFrom, mergedDate); } return mergedDate; 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 e028983db3f2..cb2d63d0a16e 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldCharacterEditing.ts @@ -341,7 +341,6 @@ export const useFieldCharacterEditing = < if (activeSection.type === 'month') { const hasLeadingZerosInFormat = doesSectionFormatHaveLeadingZeros( utils, - timezone, 'digit', 'month', 'MM', @@ -381,7 +380,7 @@ export const useFieldCharacterEditing = < return response; } - const formattedValue = getDaysInWeekStr(utils, timezone, activeSection.format)[ + const formattedValue = getDaysInWeekStr(utils, activeSection.format)[ Number(response.sectionValue) - 1 ]; return { 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 846ab4be676d..0e87524ab21e 100644 --- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts +++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts @@ -136,7 +136,6 @@ export const useFieldState = < fieldValueManager.getSectionsFromValue(utils, value, fallbackSections, (date) => buildSectionsFromFormat({ utils, - timezone, localeText: translations, localizedDigits, format, @@ -156,7 +155,6 @@ export const useFieldState = < shouldRespectLeadingZeros, utils, formatDensity, - timezone, enableAccessibleFieldDOMStructure, ], ); @@ -286,7 +284,6 @@ export const useFieldState = < const sections = buildSectionsFromFormat({ utils, - timezone, localeText: translations, localizedDigits, format, @@ -296,7 +293,7 @@ export const useFieldState = < enableAccessibleFieldDOMStructure, isRtl, }); - return mergeDateIntoReferenceDate(utils, timezone, date, sections, referenceDate, false); + return mergeDateIntoReferenceDate(utils, date, sections, referenceDate, false); }; const newValue = fieldValueManager.parseValueStr(valueStr, state.referenceValue, parseDateStr); @@ -345,7 +342,6 @@ export const useFieldState = < if (newActiveDate != null && utils.isValid(newActiveDate)) { const mergedDate = mergeDateIntoReferenceDate( utils, - timezone, newActiveDate, newActiveDateSections, activeDateManager.referenceDate, 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 63f734258bb4..89108c2cb621 100644 --- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx +++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx @@ -73,7 +73,7 @@ export const useMobilePicker = < layoutProps, renderCurrentView, fieldProps: pickerFieldProps, - fieldContextValue, + contextValue, } = usePicker({ ...pickerParams, props, @@ -160,7 +160,7 @@ export const useMobilePicker = < const handleFieldRef = useForkRef(fieldRef, fieldProps.unstableFieldRef); const renderPicker = () => ( - + ( + const contextValue = React.useMemo( () => ({ onToggleView: (event) => { if (isOpen) { @@ -477,6 +477,6 @@ export const usePickerValue = < viewProps: viewResponse, layoutProps: layoutResponse, actions, - fieldContextValue, + contextValue, }; }; 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 81ca78cfe872..5b5952a1d3d0 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 @@ -328,5 +328,5 @@ export interface UsePickerValueResponse; fieldProps: UsePickerValueFieldResponse; layoutProps: UsePickerValueLayoutResponse; - fieldContextValue: PickersContextValue; + contextValue: PickersContextValue; } diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json index 3901b785a96a..c0c3e0d39b25 100644 --- a/scripts/x-date-pickers-pro.exports.json +++ b/scripts/x-date-pickers-pro.exports.json @@ -413,13 +413,13 @@ { "name": "UseDateRangeFieldProps", "kind": "Interface" }, { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, - { "name": "useFieldPlaceholder", "kind": "Variable" }, { "name": "UseMultiInputDateRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputDateRangeFieldProps", "kind": "Interface" }, { "name": "UseMultiInputDateTimeRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputDateTimeRangeFieldProps", "kind": "Interface" }, { "name": "UseMultiInputTimeRangeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseMultiInputTimeRangeFieldProps", "kind": "Interface" }, + { "name": "useParsedFormat", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, { "name": "usePickersContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json index b2f7126714e4..e432b56a60af 100644 --- a/scripts/x-date-pickers.exports.json +++ b/scripts/x-date-pickers.exports.json @@ -304,7 +304,7 @@ { "name": "UseDateFieldProps", "kind": "Interface" }, { "name": "UseDateTimeFieldComponentProps", "kind": "TypeAlias" }, { "name": "UseDateTimeFieldProps", "kind": "Interface" }, - { "name": "useFieldPlaceholder", "kind": "Variable" }, + { "name": "useParsedFormat", "kind": "Variable" }, { "name": "usePickerLayout", "kind": "ExportAssignment" }, { "name": "usePickersContext", "kind": "Variable" }, { "name": "usePickersTranslations", "kind": "Variable" }, From 9d5e300105bf1b857d8422dc5b9a85ad60256837 Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 7 Oct 2024 12:51:27 +0200 Subject: [PATCH 26/33] Replace toggling method with onClose and onOpen --- .../custom-behavior/ReadOnlyMaterialTextField.js | 10 +++++++++- .../custom-behavior/ReadOnlyMaterialTextField.tsx | 10 +++++++++- .../src/internals/components/PickersProvider.tsx | 13 +++++++++++-- .../src/internals/hooks/usePicker/usePickerValue.ts | 10 +++------- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 35d02256eea5..45c2c9378c81 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -26,6 +26,14 @@ function ReadOnlyDateField(props) { props: internalProps, }); + const handleTogglePicker = (event) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + return ( ); } diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx index 4f92a727223c..4e247a3edb8c 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx @@ -30,6 +30,14 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { props: internalProps, }); + const handleTogglePicker = (event: React.UIEvent) => { + if (pickersContext.open) { + pickersContext.onClose(event); + } else { + pickersContext.onOpen(event); + } + }; + return ( ) { placeholder={parsedFormat} InputProps={{ ...InputProps, readOnly: true }} error={hasValidationError} - onClick={pickersContext.onToggleView} + onClick={handleTogglePicker} /> ); } diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index faeea0b8da85..7666c747127a 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -32,8 +32,17 @@ interface PickersFieldProviderProps { export interface PickersContextValue { /** - * Open the view if they are closed, close them otherwise. + * Open the picker if it is closed. * @param {React.UIEvent} event The DOM event that triggered the change. */ - onToggleView: (event: React.UIEvent) => void; + onOpen: (event: React.UIEvent) => void; + /** + * Close the picker if it is opened. + * @param {React.UIEvent} event The DOM event that triggered the change. + */ + onClose: (event: React.UIEvent) => void; + /** + * `true` if the picker is open, `false` otherwise. + */ + open: boolean; } 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 9f7b2bfe21ae..ae7553494e0a 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts @@ -460,13 +460,9 @@ export const usePickerValue = < const contextValue = React.useMemo( () => ({ - onToggleView: (event) => { - if (isOpen) { - handleClose(event); - } else { - handleOpen(event); - } - }, + onOpen: handleOpen, + onClose: handleClose, + open: isOpen, }), [isOpen, handleClose, handleOpen], ); From 3e976f809c1200dc5e597f13a3891d52dcc46e88 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 7 Oct 2024 13:07:11 +0200 Subject: [PATCH 27/33] Update packages/x-date-pickers/src/internals/components/PickersProvider.tsx Co-authored-by: Lukas Tyla Signed-off-by: Flavien DELANGLE --- .../x-date-pickers/src/internals/components/PickersProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index 7666c747127a..41a970d3850e 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -32,7 +32,7 @@ interface PickersFieldProviderProps { export interface PickersContextValue { /** - * Open the picker if it is closed. + * Open the picker. * @param {React.UIEvent} event The DOM event that triggered the change. */ onOpen: (event: React.UIEvent) => void; From f5b950e68946473be1fbf1cf130ff8937c332346 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 7 Oct 2024 13:07:23 +0200 Subject: [PATCH 28/33] Update packages/x-date-pickers/src/internals/components/PickersProvider.tsx Co-authored-by: Lukas Tyla Signed-off-by: Flavien DELANGLE --- .../x-date-pickers/src/internals/components/PickersProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx index 41a970d3850e..8dd0654a846c 100644 --- a/packages/x-date-pickers/src/internals/components/PickersProvider.tsx +++ b/packages/x-date-pickers/src/internals/components/PickersProvider.tsx @@ -37,7 +37,7 @@ export interface PickersContextValue { */ onOpen: (event: React.UIEvent) => void; /** - * Close the picker if it is opened. + * Close the picker. * @param {React.UIEvent} event The DOM event that triggered the change. */ onClose: (event: React.UIEvent) => void; From 80e16b4babcbd50fe81582e5c49f0d8ceea9f7e3 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 7 Oct 2024 13:07:29 +0200 Subject: [PATCH 29/33] Update packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts Co-authored-by: Lukas Tyla Signed-off-by: Flavien DELANGLE --- .../x-date-pickers/src/internals/hooks/usePicker/usePicker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f1ae7f602e6f..3d290f0ded8c 100644 --- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts +++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts @@ -85,7 +85,7 @@ export const usePicker = < // Picker layout layoutProps: pickerLayoutResponse.layoutProps, - // Picker field + // Picker context contextValue: pickerValueResponse.contextValue, }; }; From 2fd6a5a18477124613ed1cf67fba8f731ef880eb Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 7 Oct 2024 13:07:42 +0200 Subject: [PATCH 30/33] Update packages/x-date-pickers/src/hooks/useParsedFormat.ts Co-authored-by: Lukas Tyla Signed-off-by: Flavien DELANGLE --- packages/x-date-pickers/src/hooks/useParsedFormat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/hooks/useParsedFormat.ts b/packages/x-date-pickers/src/hooks/useParsedFormat.ts index 579356224ebe..c5e901ee9c7b 100644 --- a/packages/x-date-pickers/src/hooks/useParsedFormat.ts +++ b/packages/x-date-pickers/src/hooks/useParsedFormat.ts @@ -15,7 +15,7 @@ interface UseParsedFormatParameters > {} /** - * Returns the parsed format to be rendered in the field when their is no value or in other parts of the picker. + * Returns the parsed format to be rendered in the field when there is no value or in other parts of the Picker. * This format is localized (e.g: `AAAA` for the year with the French locale) and cannot be parsed by your date library. * @param {object} The parameters needed to build the placeholder. * @param {string} params.format Format of the date to use. From 9443b65086bcbbfac3c67fa92d9edcd7cb53c785 Mon Sep 17 00:00:00 2001 From: Flavien DELANGLE Date: Mon, 7 Oct 2024 13:08:53 +0200 Subject: [PATCH 31/33] Update packages/x-date-pickers/src/hooks/usePickersContext.ts Co-authored-by: Lukas Tyla Signed-off-by: Flavien DELANGLE --- packages/x-date-pickers/src/hooks/usePickersContext.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-date-pickers/src/hooks/usePickersContext.ts b/packages/x-date-pickers/src/hooks/usePickersContext.ts index 9b6cc1c23e62..1303af42b886 100644 --- a/packages/x-date-pickers/src/hooks/usePickersContext.ts +++ b/packages/x-date-pickers/src/hooks/usePickersContext.ts @@ -3,7 +3,7 @@ import * as React from 'react'; import { PickersContext } from '../internals/components/PickersProvider'; /** - * Returns the context passed by the picker the wraps the current component. + * Returns the context passed by the picker that wraps the current component. */ export const usePickersContext = () => { const value = React.useContext(PickersContext); From 018158d987847b8de33bd848d8bf756b72ccd5da Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 7 Oct 2024 14:00:06 +0200 Subject: [PATCH 32/33] Improve demo --- .../custom-behavior/ReadOnlyMaterialTextField.js | 10 +++++++++- .../custom-behavior/ReadOnlyMaterialTextField.tsx | 8 +++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 45c2c9378c81..251390d64135 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -10,6 +10,7 @@ import { useParsedFormat, usePickersContext, } from '@mui/x-date-pickers/hooks'; +import { CalendarIcon } from '@mui/x-date-pickers/icons'; function ReadOnlyDateField(props) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); @@ -34,12 +35,19 @@ function ReadOnlyDateField(props) { } }; + console.log(InputProps); + return ( , + sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, + }} error={hasValidationError} onClick={handleTogglePicker} /> diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx index 4e247a3edb8c..c9cdc16eae4e 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.tsx @@ -14,6 +14,7 @@ import { useParsedFormat, usePickersContext, } from '@mui/x-date-pickers/hooks'; +import { CalendarIcon } from '@mui/x-date-pickers/icons'; function ReadOnlyDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); @@ -43,7 +44,12 @@ function ReadOnlyDateField(props: DatePickerFieldProps) { {...other} value={value == null ? '' : value.format(format)} placeholder={parsedFormat} - InputProps={{ ...InputProps, readOnly: true }} + InputProps={{ + ...InputProps, + readOnly: true, + endAdornment: , + sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, + }} error={hasValidationError} onClick={handleTogglePicker} /> From 70b1bef9076f8eb6652e8d9af3b4fbaf0b182806 Mon Sep 17 00:00:00 2001 From: flavien Date: Mon, 7 Oct 2024 14:08:37 +0200 Subject: [PATCH 33/33] Fix --- .../custom-field/custom-behavior/ReadOnlyMaterialTextField.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js index 251390d64135..b5050747ff1f 100644 --- a/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js +++ b/docs/data/date-pickers/custom-field/custom-behavior/ReadOnlyMaterialTextField.js @@ -35,8 +35,6 @@ function ReadOnlyDateField(props) { } }; - console.log(InputProps); - return (