-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pickers] Strictly type the props a picker passes to its field, and migrate all the custom field demos accordingly #15197
Changes from all commits
59c8cd5
5b0029f
33bdaff
22ec31d
e04759c
9f13aae
3436184
c8f4de7
9592ee9
a67429c
380c3bc
94e2bef
e040f2e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,21 +5,17 @@ import { styled } from '@mui/material/styles'; | |
import Stack from '@mui/material/Stack'; | ||
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; | ||
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the assumptions and the resulting compromises. 👍 |
||
import { PickerValidDate } from '@mui/x-date-pickers/models'; | ||
import { | ||
DateRangePicker, | ||
DateRangePickerFieldProps, | ||
DateRangePickerProps, | ||
} from '@mui/x-date-pickers-pro/DateRangePicker'; | ||
import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; | ||
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; | ||
import { | ||
RangeFieldSection, | ||
BaseMultiInputFieldProps, | ||
BasePickersTextFieldProps, | ||
MultiInputFieldSlotTextFieldProps, | ||
DateRangeValidationError, | ||
DateRange, | ||
UseDateRangeFieldProps, | ||
MultiInputFieldRefs, | ||
BaseMultiInputPickersTextFieldProps, | ||
} from '@mui/x-date-pickers-pro/models'; | ||
|
||
const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ | ||
|
@@ -38,14 +34,12 @@ const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content | |
); | ||
|
||
interface BrowserTextFieldProps | ||
extends BasePickersTextFieldProps<true>, | ||
extends BaseMultiInputPickersTextFieldProps<true>, | ||
Omit< | ||
React.HTMLAttributes<HTMLDivElement>, | ||
keyof BasePickersTextFieldProps<true> | ||
keyof BaseMultiInputPickersTextFieldProps<true> | ||
> {} | ||
|
||
// This demo uses `BasePickersTextFieldProps` instead of `BaseMultiInputPickersTextFieldProps`, | ||
// That way you can reuse the same `BrowserTextField` for all your pickers, range or not. | ||
const BrowserTextField = React.forwardRef( | ||
(props: BrowserTextFieldProps, ref: React.Ref<unknown>) => { | ||
const { | ||
|
@@ -108,14 +102,11 @@ const BrowserTextField = React.forwardRef( | |
); | ||
|
||
interface BrowserMultiInputDateRangeFieldProps | ||
extends UseDateRangeFieldProps<true>, | ||
BaseMultiInputFieldProps< | ||
// This usage of PickerValidDate will go away with TIsRange | ||
DateRange<PickerValidDate>, | ||
RangeFieldSection, | ||
true, | ||
DateRangeValidationError | ||
> {} | ||
extends Omit< | ||
DateRangePickerFieldProps, | ||
'unstableFieldRef' | 'clearable' | 'onClear' | ||
>, | ||
MultiInputFieldRefs {} | ||
|
||
type BrowserMultiInputDateRangeFieldComponent = (( | ||
props: BrowserMultiInputDateRangeFieldProps & React.RefAttributes<HTMLDivElement>, | ||
|
@@ -126,12 +117,10 @@ const BrowserMultiInputDateRangeField = React.forwardRef( | |
const { | ||
slotProps, | ||
value, | ||
defaultValue, | ||
format, | ||
onChange, | ||
readOnly, | ||
disabled, | ||
onError, | ||
shouldDisableDate, | ||
minDate, | ||
maxDate, | ||
|
@@ -162,12 +151,10 @@ const BrowserMultiInputDateRangeField = React.forwardRef( | |
>({ | ||
sharedProps: { | ||
value, | ||
defaultValue, | ||
format, | ||
onChange, | ||
readOnly, | ||
disabled, | ||
onError, | ||
shouldDisableDate, | ||
minDate, | ||
maxDate, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,25 +9,14 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; | |
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These changes look epic and way cleaner without the need to control nested slotProps. 🎉 |
||
import { | ||
DateRangePicker, | ||
DateRangePickerFieldProps, | ||
DateRangePickerProps, | ||
} from '@mui/x-date-pickers-pro/DateRangePicker'; | ||
import { | ||
unstable_useSingleInputDateRangeField as useSingleInputDateRangeField, | ||
UseSingleInputDateRangeFieldProps, | ||
} from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; | ||
import { useClearableField } from '@mui/x-date-pickers/hooks'; | ||
import { unstable_useSingleInputDateRangeField as useSingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; | ||
import { useClearableField, usePickerContext } from '@mui/x-date-pickers/hooks'; | ||
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; | ||
import { | ||
BasePickersTextFieldProps, | ||
DateRangeValidationError, | ||
RangeFieldSection, | ||
DateRange, | ||
FieldType, | ||
} from '@mui/x-date-pickers-pro/models'; | ||
import { | ||
BaseSingleInputFieldProps, | ||
PickerValidDate, | ||
} from '@mui/x-date-pickers/models'; | ||
import { FieldType } from '@mui/x-date-pickers-pro/models'; | ||
import { BaseSingleInputPickersTextFieldProps } from '@mui/x-date-pickers/models'; | ||
|
||
const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ | ||
display: 'flex', | ||
|
@@ -48,10 +37,10 @@ const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content | |
); | ||
|
||
interface BrowserTextFieldProps | ||
extends BasePickersTextFieldProps<true>, | ||
extends BaseSingleInputPickersTextFieldProps<true>, | ||
Omit< | ||
React.HTMLAttributes<HTMLDivElement>, | ||
keyof BasePickersTextFieldProps<true> | ||
keyof BaseSingleInputPickersTextFieldProps<true> | ||
> {} | ||
|
||
const BrowserTextField = React.forwardRef( | ||
|
@@ -115,25 +104,24 @@ const BrowserTextField = React.forwardRef( | |
}, | ||
); | ||
|
||
interface BrowserSingleInputDateRangeFieldProps | ||
extends UseSingleInputDateRangeFieldProps<true>, | ||
BaseSingleInputFieldProps< | ||
// This usage of PickerValidDate will go away with TIsRange | ||
DateRange<PickerValidDate>, | ||
RangeFieldSection, | ||
true, | ||
DateRangeValidationError | ||
> { | ||
onAdornmentClick?: () => void; | ||
} | ||
interface BrowserSingleInputDateRangeFieldProps extends DateRangePickerFieldProps {} | ||
|
||
type BrowserSingleInputDateRangeFieldComponent = (( | ||
props: BrowserSingleInputDateRangeFieldProps & React.RefAttributes<HTMLDivElement>, | ||
) => React.JSX.Element) & { fieldType?: FieldType }; | ||
|
||
const BrowserSingleInputDateRangeField = React.forwardRef( | ||
(props: BrowserSingleInputDateRangeFieldProps, ref: React.Ref<HTMLDivElement>) => { | ||
const { slots, slotProps, onAdornmentClick, ...other } = props; | ||
const { slots, slotProps, ...other } = props; | ||
|
||
const pickerContext = usePickerContext(); | ||
const handleTogglePicker = (event: React.UIEvent) => { | ||
if (pickerContext.open) { | ||
pickerContext.onClose(event); | ||
} else { | ||
pickerContext.onOpen(event); | ||
} | ||
}; | ||
|
||
const textFieldProps: typeof props = useSlotProps({ | ||
elementType: 'input', | ||
|
@@ -146,7 +134,7 @@ const BrowserSingleInputDateRangeField = React.forwardRef( | |
...textFieldProps.InputProps, | ||
endAdornment: ( | ||
<InputAdornment position="end"> | ||
<IconButton onClick={onAdornmentClick}> | ||
<IconButton onClick={handleTogglePicker}> | ||
<DateRangeIcon /> | ||
</IconButton> | ||
</InputAdornment> | ||
|
@@ -180,29 +168,11 @@ BrowserSingleInputDateRangeField.fieldType = 'single-input'; | |
|
||
const BrowserSingleInputDateRangePicker = React.forwardRef( | ||
(props: DateRangePickerProps, ref: React.Ref<HTMLDivElement>) => { | ||
const [isOpen, setIsOpen] = React.useState(false); | ||
|
||
const toggleOpen = () => setIsOpen((currentOpen) => !currentOpen); | ||
|
||
const handleOpen = () => setIsOpen(true); | ||
|
||
const handleClose = () => setIsOpen(false); | ||
|
||
return ( | ||
<DateRangePicker | ||
ref={ref} | ||
{...props} | ||
open={isOpen} | ||
onClose={handleClose} | ||
onOpen={handleOpen} | ||
slots={{ ...props.slots, field: BrowserSingleInputDateRangeField }} | ||
slotProps={{ | ||
...props.slotProps, | ||
field: { | ||
onAdornmentClick: toggleOpen, | ||
...props.slotProps?.field, | ||
} as any, | ||
}} | ||
/> | ||
); | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DatePickerFieldProps
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks immensely cleaner. 😱 💯