Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[pickers] Let the field components handle their opening UI, and allow field editing on mobile pickers #15671

Draft
wants to merge 107 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
5f11d82
[pickers] Move the field opening logic inside the field components
flaviendelangle Nov 29, 2024
4f734a8
Try to support range field
flaviendelangle Nov 29, 2024
8335ea4
Work
flaviendelangle Nov 29, 2024
20f6337
Regen API
flaviendelangle Nov 29, 2024
26e641d
Work
flaviendelangle Nov 29, 2024
b84e04c
Fix TS
flaviendelangle Nov 29, 2024
f65cf67
Fix
flaviendelangle Nov 29, 2024
6a46821
Hide opening ui on range pickers
flaviendelangle Nov 29, 2024
2c9669b
Fix
flaviendelangle Nov 29, 2024
ab16f5c
Fix
flaviendelangle Nov 29, 2024
b8eb609
Merge branch 'master' into opening-field
flaviendelangle Nov 29, 2024
ec32af7
Fix doc
flaviendelangle Nov 29, 2024
d94e368
Fix doc
flaviendelangle Nov 29, 2024
37aed61
Work
flaviendelangle Nov 29, 2024
e3f8964
Work
flaviendelangle Nov 29, 2024
6af3e7c
Fix
flaviendelangle Nov 29, 2024
6f499e0
Fix
flaviendelangle Nov 29, 2024
f4d10a2
Merge branch 'master' into opening-field
flaviendelangle Nov 29, 2024
c4e803b
Fix
flaviendelangle Nov 29, 2024
0274ae2
Fix
flaviendelangle Nov 29, 2024
5d6525b
Empty
flaviendelangle Nov 29, 2024
8a218a7
Work
flaviendelangle Nov 29, 2024
b1e685b
Work
flaviendelangle Nov 29, 2024
63af290
Merge branch 'master' into opening-field
flaviendelangle Dec 2, 2024
da6aa21
Work
flaviendelangle Dec 2, 2024
5e0edb3
Fix
flaviendelangle Dec 2, 2024
2282675
Work on tests
flaviendelangle Dec 2, 2024
d93c25b
Fix
flaviendelangle Dec 2, 2024
df85077
Fix
flaviendelangle Dec 2, 2024
00f7c3c
Fix
flaviendelangle Dec 2, 2024
6003978
Fix
flaviendelangle Dec 2, 2024
02a07b0
Fix
flaviendelangle Dec 2, 2024
6a98cdf
Fix
flaviendelangle Dec 2, 2024
8b19254
Fix
flaviendelangle Dec 2, 2024
e22c78f
Fix
flaviendelangle Dec 2, 2024
aeddc0d
[pickers] Add new method onToggleOpening to the picker public context
flaviendelangle Dec 2, 2024
df6b7f3
Merge branch 'master' into opening-field
flaviendelangle Dec 2, 2024
dc25276
Merge branch 'master' into opening-field
flaviendelangle Dec 3, 2024
2db9946
Fix
flaviendelangle Dec 3, 2024
072e0ce
[docs] Clean Joy and Browser custom field demos
flaviendelangle Dec 3, 2024
114bebe
Merge branch 'master' into joy-browser-demos
flaviendelangle Dec 3, 2024
26b4206
Replace all the opening methods with setOpen
flaviendelangle Dec 4, 2024
c0e4ced
Add migration guide
flaviendelangle Dec 4, 2024
36fdd0d
Merge branch 'master' into joy-browser-demos
flaviendelangle Dec 4, 2024
496340e
Clean useGetOpenDialogAriaLabel
flaviendelangle Dec 4, 2024
92647ea
Merge branch 'master' into opening-field
flaviendelangle Dec 4, 2024
93e4b03
Work
flaviendelangle Dec 4, 2024
ef53874
Update docs/data/migration/migration-pickers-v7/migration-pickers-v7.md
flaviendelangle Dec 4, 2024
c047749
Update packages/x-date-pickers/src/internals/hooks/usePicker/usePicke…
flaviendelangle Dec 4, 2024
e00ff3a
Update packages/x-date-pickers/src/internals/hooks/usePicker/usePicke…
flaviendelangle Dec 4, 2024
58e722c
Update packages/x-date-pickers/src/internals/hooks/usePicker/usePicke…
flaviendelangle Dec 4, 2024
e2f56b6
Work
flaviendelangle Dec 4, 2024
fcbcce6
Work
flaviendelangle Dec 4, 2024
756c6d8
Merge branch 'master' into ctx-onToggleOpening
flaviendelangle Dec 4, 2024
8b500ac
Merge remote-tracking branch 'origin/ctx-onToggleOpening' into ctx-on…
flaviendelangle Dec 4, 2024
e20d8bc
Merge branch 'ctx-onToggleOpening' into opening-field
flaviendelangle Dec 4, 2024
d5b36e5
Merge branch 'master' into ctx-onToggleOpening
flaviendelangle Dec 4, 2024
a004cfb
Merge branch 'ctx-onToggleOpening' into opening-field
flaviendelangle Dec 4, 2024
4b4d59d
Merge branch 'master' into joy-browser-demos
flaviendelangle Dec 4, 2024
f605416
Merge
flaviendelangle Dec 4, 2024
1fa2803
Merge
flaviendelangle Dec 4, 2024
673e615
Simplify
flaviendelangle Dec 4, 2024
6dbac5a
Fix
flaviendelangle Dec 4, 2024
cca4be1
Fix
flaviendelangle Dec 4, 2024
119a26e
Work
flaviendelangle Dec 4, 2024
4927e7f
Work
flaviendelangle Dec 4, 2024
05ce330
Fix
flaviendelangle Dec 4, 2024
ebbfa1a
Merge branch 'master' into opening-field
flaviendelangle Dec 4, 2024
034d7a1
Fine tune the doc demos
flaviendelangle Dec 5, 2024
bd77821
Fine tune the doc demos
flaviendelangle Dec 5, 2024
536588c
Fix doc
flaviendelangle Dec 5, 2024
3a27864
Fix doc
flaviendelangle Dec 5, 2024
7fbdac6
Add migration guide
flaviendelangle Dec 5, 2024
9724454
Fix doc
flaviendelangle Dec 5, 2024
d90412a
Fix
flaviendelangle Dec 5, 2024
307b1b8
Fix doc
flaviendelangle Dec 5, 2024
108539a
Work on migration guid
flaviendelangle Dec 5, 2024
f2691ba
Fix doc
flaviendelangle Dec 5, 2024
14b2252
Fix
flaviendelangle Dec 5, 2024
3c337ad
Fix test
flaviendelangle Dec 6, 2024
6502e1c
Fix test
flaviendelangle Dec 6, 2024
40c8d0d
Fix test
flaviendelangle Dec 6, 2024
489c46c
Merge branch 'master' into opening-field
flaviendelangle Dec 6, 2024
fd1c3f2
Merge branch 'master' into joy-browser-demos
flaviendelangle Dec 6, 2024
804de60
Merge
flaviendelangle Dec 6, 2024
e37bf2d
Work
flaviendelangle Dec 6, 2024
cf594f1
Fix
flaviendelangle Dec 6, 2024
301af07
Work
flaviendelangle Dec 6, 2024
ff14cb0
Merge
flaviendelangle Dec 6, 2024
1a34f50
Work
flaviendelangle Dec 6, 2024
52b12f1
Work
flaviendelangle Dec 6, 2024
a791ea8
Work
flaviendelangle Dec 6, 2024
5d6ec7b
Work
flaviendelangle Dec 6, 2024
ec98144
Work
flaviendelangle Dec 6, 2024
07b0814
Work
flaviendelangle Dec 6, 2024
5f9d482
Merge branch 'master' into joy-browser-demos
flaviendelangle Dec 6, 2024
e77bbf3
Fix
flaviendelangle Dec 6, 2024
f3876fb
Merge remote-tracking branch 'origin/joy-browser-demos' into joy-brow…
flaviendelangle Dec 6, 2024
9cf1528
Merge
flaviendelangle Dec 6, 2024
1b01fa4
Merge
flaviendelangle Dec 6, 2024
34188f5
Fix
flaviendelangle Dec 6, 2024
279c5b8
Merge branch 'master' into opening-field
flaviendelangle Dec 9, 2024
1755828
Work
flaviendelangle Dec 9, 2024
f4d1bc9
Fix
flaviendelangle Dec 9, 2024
199ea17
Merge branch 'master' into opening-field
flaviendelangle Dec 11, 2024
bc20321
Fix doc
flaviendelangle Dec 11, 2024
61fc6d5
Fix doc
flaviendelangle Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/data/date-pickers/base-concepts/base-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ Each _Picker_ is available in a responsive, desktop and mobile variant:
- The responsive component (for example `DatePicker`) which renders the desktop component or the mobile one depending on the device it runs on.

- The desktop component (for example `DesktopDatePicker`) which works best for mouse devices and large screens.
It renders the views inside a popover and allows editing values directly inside the field.
It renders the views inside a popover and a field for keyboard editing.

- The mobile component (for example `MobileDatePicker`) which works best for touch devices and small screens.
It renders the view inside a modal and does not allow editing values directly inside the field.
It renders the view inside a modal and a field for keyboard editing.

{{"demo": "ResponsivePickers.js"}}

Expand Down
14 changes: 3 additions & 11 deletions docs/data/date-pickers/calendar-systems/AdapterHijri.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,8 @@ const cacheRtl = createCache({
function ButtonDateTimeField(props) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { value, timezone, format } = internalProps;
const {
InputProps,
slotProps,
slots,
ownerState,
label,
focused,
name,
...other
} = forwardedProps;
const { slotProps, slots, ownerState, label, focused, name, ...other } =
forwardedProps;

const pickerContext = usePickerContext();

Expand All @@ -53,7 +45,7 @@ function ButtonDateTimeField(props) {
{...other}
variant="outlined"
color={hasValidationError ? 'error' : 'primary'}
ref={InputProps?.ref}
ref={pickerContext.triggerRef}
onClick={() => pickerContext.setOpen((prev) => !prev)}
>
{label ? `${label}: ${valueStr}` : valueStr}
Expand Down
14 changes: 3 additions & 11 deletions docs/data/date-pickers/calendar-systems/AdapterHijri.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,8 @@ const cacheRtl = createCache({
function ButtonDateTimeField(props: DateTimePickerFieldProps) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { value, timezone, format } = internalProps;
const {
InputProps,
slotProps,
slots,
ownerState,
label,
focused,
name,
...other
} = forwardedProps;
const { slotProps, slots, ownerState, label, focused, name, ...other } =
forwardedProps;

const pickerContext = usePickerContext();

Expand All @@ -57,7 +49,7 @@ function ButtonDateTimeField(props: DateTimePickerFieldProps) {
{...other}
variant="outlined"
color={hasValidationError ? 'error' : 'primary'}
ref={InputProps?.ref}
ref={pickerContext.triggerRef}
onClick={() => pickerContext.setOpen((prev) => !prev)}
>
{label ? `${label}: ${valueStr}` : valueStr}
Expand Down
18 changes: 14 additions & 4 deletions docs/data/date-pickers/custom-field/BrowserV7Field.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import * as React from 'react';
import useForkRef from '@mui/utils/useForkRef';
import { styled } from '@mui/material/styles';
import IconButton from '@mui/material/IconButton';
import { CalendarIcon } from '@mui/x-date-pickers/icons';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField';
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList';
import { usePickerContext } from '@mui/x-date-pickers/hooks';

const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({
display: 'flex',
Expand Down Expand Up @@ -41,6 +44,8 @@ const BrowserDateField = React.forwardRef((props, ref) => {
onInput,
onPaste,
onKeyDown,
// Should be passed to the button that opens the picker
openPickerAriaLabel,
// Can be passed to a hidden <input /> element
onChange,
value,
Expand All @@ -55,16 +60,15 @@ const BrowserDateField = React.forwardRef((props, ref) => {
readOnly,
focused,
error,
InputProps: { ref: InputPropsRef, startAdornment, endAdornment } = {},
// The rest can be passed to the root element
...other
} = fieldResponse;

const handleRef = useForkRef(InputPropsRef, ref);
const pickerContext = usePickerContext();
const handleRef = useForkRef(pickerContext.triggerRef, ref);

return (
<BrowserFieldRoot ref={handleRef} {...other}>
{startAdornment}
<BrowserFieldContent>
<PickersSectionList
elements={elements}
Expand All @@ -78,7 +82,13 @@ const BrowserDateField = React.forwardRef((props, ref) => {
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
{endAdornment}
<IconButton
onClick={() => pickerContext.setOpen((prev) => !prev)}
sx={{ marginLeft: 1.5 }}
aria-label={openPickerAriaLabel}
>
<CalendarIcon />
</IconButton>
</BrowserFieldRoot>
);
});
Expand Down
20 changes: 15 additions & 5 deletions docs/data/date-pickers/custom-field/BrowserV7Field.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react';
import useForkRef from '@mui/utils/useForkRef';
import { styled } from '@mui/material/styles';
import IconButton from '@mui/material/IconButton';
import { CalendarIcon } from '@mui/x-date-pickers/icons';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import {
Expand All @@ -10,6 +12,7 @@ import {
} from '@mui/x-date-pickers/DatePicker';
import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField';
import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList';
import { usePickerContext } from '@mui/x-date-pickers/hooks';

const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({
display: 'flex',
Expand Down Expand Up @@ -48,6 +51,9 @@ const BrowserDateField = React.forwardRef(
onPaste,
onKeyDown,

// Should be passed to the button that opens the picker
openPickerAriaLabel,

// Can be passed to a hidden <input /> element
onChange,
value,
Expand All @@ -66,17 +72,15 @@ const BrowserDateField = React.forwardRef(
focused,
error,

InputProps: { ref: InputPropsRef, startAdornment, endAdornment } = {},

// The rest can be passed to the root element
...other
} = fieldResponse;

const handleRef = useForkRef(InputPropsRef, ref);
const pickerContext = usePickerContext();
const handleRef = useForkRef(pickerContext.triggerRef, ref);

return (
<BrowserFieldRoot ref={handleRef} {...other}>
{startAdornment}
<BrowserFieldContent>
<PickersSectionList
elements={elements}
Expand All @@ -90,7 +94,13 @@ const BrowserDateField = React.forwardRef(
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
{endAdornment}
<IconButton
onClick={() => pickerContext.setOpen((prev) => !prev)}
sx={{ marginLeft: 1.5 }}
aria-label={openPickerAriaLabel}
>
<CalendarIcon />
</IconButton>
</BrowserFieldRoot>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
const startTextFieldProps = useSlotProps({
elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { ...props, position: 'start' },
ownerState: {},
});

const endTextFieldProps = useSlotProps({
elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { ...props, position: 'end' },
ownerState: {},
});

const fieldResponse = useMultiInputDateRangeField({
Expand All @@ -131,6 +131,19 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
unstableEndFieldRef,
});

const {
onClear: onClearStartDate,
clearable: isStartDateClearable,
openPickerAriaLabel: openPickerStartDateAriaLabel,
...startDateProps
} = fieldResponse.startDate;
const {
onClear: onClearEndDate,
clearable: isEndDateClearable,
openPickerAriaLabel: openPickerEndDateAriaLabel,
...endDateProps
} = fieldResponse.endDate;

return (
<Stack
ref={ref}
Expand All @@ -139,9 +152,9 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
overflow="auto"
className={className}
>
<BrowserTextField {...fieldResponse.startDate} />
<BrowserTextField {...startDateProps} />
<span> — </span>
<BrowserTextField {...fieldResponse.endDate} />
<BrowserTextField {...endDateProps} />
</Stack>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ const BrowserMultiInputDateRangeField = React.forwardRef(
const startTextFieldProps = useSlotProps({
elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { ...props, position: 'start' },
ownerState: {} as any,
}) as MultiInputFieldSlotTextFieldProps;

const endTextFieldProps = useSlotProps({
elementType: 'input',
externalSlotProps: slotProps?.textField,
ownerState: { ...props, position: 'end' },
ownerState: {} as any,
}) as MultiInputFieldSlotTextFieldProps;

const fieldResponse = useMultiInputDateRangeField<
Expand Down Expand Up @@ -170,6 +170,19 @@ const BrowserMultiInputDateRangeField = React.forwardRef(
unstableEndFieldRef,
});

const {
onClear: onClearStartDate,
clearable: isStartDateClearable,
openPickerAriaLabel: openPickerStartDateAriaLabel,
...startDateProps
} = fieldResponse.startDate;
const {
onClear: onClearEndDate,
clearable: isEndDateClearable,
openPickerAriaLabel: openPickerEndDateAriaLabel,
...endDateProps
} = fieldResponse.endDate;

return (
<Stack
ref={ref}
Expand All @@ -178,9 +191,9 @@ const BrowserMultiInputDateRangeField = React.forwardRef(
overflow="auto"
className={className}
>
<BrowserTextField {...fieldResponse.startDate} />
<BrowserTextField {...startDateProps} />
<span> — </span>
<BrowserTextField {...fieldResponse.endDate} />
<BrowserTextField {...endDateProps} />
</Stack>
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,12 @@ const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => {
readOnly,
focused,
error,
InputProps: { ref: InputPropsRef, startAdornment, endAdornment } = {},
// The rest can be passed to the root element
...other
} = fieldResponse;

const pickerContext = usePickerContext();
const handleRef = useForkRef(InputPropsRef, ref);
const handleRef = useForkRef(pickerContext.triggerRef, ref);

return (
<BrowserFieldRoot
Expand All @@ -75,7 +74,6 @@ const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => {
minWidth: 300,
}}
>
{startAdornment}
<BrowserFieldContent>
<PickersSectionList
elements={elements}
Expand All @@ -89,7 +87,6 @@ const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => {
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
{endAdornment}
<InputAdornment position="end">
<IconButton onClick={() => pickerContext.setOpen((prev) => !prev)}>
<DateRangeIcon />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,12 @@ const BrowserSingleInputDateRangeField = React.forwardRef(
focused,
error,

InputProps: { ref: InputPropsRef, startAdornment, endAdornment } = {},

// The rest can be passed to the root element
...other
} = fieldResponse;

const pickerContext = usePickerContext();
const handleRef = useForkRef(InputPropsRef, ref);
const handleRef = useForkRef(pickerContext.triggerRef, ref);

return (
<BrowserFieldRoot
Expand All @@ -94,7 +92,6 @@ const BrowserSingleInputDateRangeField = React.forwardRef(
minWidth: 300,
}}
>
{startAdornment}
<BrowserFieldContent>
<PickersSectionList
elements={elements}
Expand All @@ -108,7 +105,6 @@ const BrowserSingleInputDateRangeField = React.forwardRef(
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
{endAdornment}
<InputAdornment position="end">
<IconButton onClick={() => pickerContext.setOpen((prev) => !prev)}>
<DateRangeIcon />
Expand Down
Loading
Loading