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] Move more field props to the context #16278

Merged
merged 28 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0b2a9a2
[pickers] Move more field props to the context
flaviendelangle Jan 21, 2025
8b82734
Work
flaviendelangle Jan 21, 2025
81815c1
Work
flaviendelangle Jan 21, 2025
3eb36a4
Work
flaviendelangle Jan 21, 2025
adbee54
Add migration guide
flaviendelangle Jan 21, 2025
e8b185e
Work on demos
flaviendelangle Jan 21, 2025
f3127ec
Work
flaviendelangle Jan 21, 2025
961ae6a
Merge branch 'master' into field-context-ui
flaviendelangle Jan 21, 2025
deb5dc3
Fix
flaviendelangle Jan 21, 2025
d6e49f1
Fix
flaviendelangle Jan 21, 2025
f0bb11a
Fix
flaviendelangle Jan 21, 2025
39ae9ae
Fix more docs demos
flaviendelangle Jan 21, 2025
ed58d9a
Fix
flaviendelangle Jan 21, 2025
7d6fbd3
Remove field ownerState
flaviendelangle Jan 22, 2025
d78b026
Merge branch 'master' into field-context-ui
flaviendelangle Jan 23, 2025
52e7629
Fix CI
flaviendelangle Jan 23, 2025
4702701
Merge branch 'master' into field-context-ui
flaviendelangle Jan 23, 2025
17b6154
Move ref to context
flaviendelangle Jan 24, 2025
f645dc7
Add migration-guide
flaviendelangle Jan 24, 2025
c5a6b8c
Work
flaviendelangle Jan 24, 2025
51ef7a0
Work
flaviendelangle Jan 24, 2025
9b9ea88
Fix
flaviendelangle Jan 24, 2025
b252aef
Merge branch 'master' into field-context-ui
flaviendelangle Jan 24, 2025
2fe7d1a
Improve JSDoc
flaviendelangle Jan 24, 2025
3cec7ee
Fix
flaviendelangle Jan 27, 2025
bae9671
Merge
flaviendelangle Jan 27, 2025
e55b74b
Merge branch 'master' into field-context-ui
flaviendelangle Jan 27, 2025
9272c3c
Fix
flaviendelangle Jan 27, 2025
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
6 changes: 4 additions & 2 deletions docs/data/date-pickers/calendar-systems/AdapterHijri.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const cacheRtl = createCache({

function ButtonDateTimeField(props) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { ownerState, label, focused, name, ...other } = forwardedProps;
const { focused, ...other } = forwardedProps;

const pickerContext = usePickerContext();
const parsedFormat = useParsedFormat();
Expand All @@ -45,10 +45,12 @@ function ButtonDateTimeField(props) {
{...other}
variant="outlined"
color={hasValidationError ? 'error' : 'primary'}
className={pickerContext.rootClassName}
sx={pickerContext.rootSx}
ref={pickerContext.triggerRef}
onClick={() => pickerContext.setOpen((prev) => !prev)}
>
{label ? `${label}: ${valueStr}` : valueStr}
{pickerContext.label ? `${pickerContext.label}: ${valueStr}` : valueStr}
</Button>
);
}
Expand Down
6 changes: 4 additions & 2 deletions docs/data/date-pickers/calendar-systems/AdapterHijri.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const cacheRtl = createCache({

function ButtonDateTimeField(props: DateTimePickerFieldProps) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { ownerState, label, focused, name, ...other } = forwardedProps;
const { focused, ...other } = forwardedProps;

const pickerContext = usePickerContext();
const parsedFormat = useParsedFormat();
Expand All @@ -49,10 +49,12 @@ function ButtonDateTimeField(props: DateTimePickerFieldProps) {
{...other}
variant="outlined"
color={hasValidationError ? 'error' : 'primary'}
className={pickerContext.rootClassName}
sx={pickerContext.rootSx}
ref={pickerContext.triggerRef}
onClick={() => pickerContext.setOpen((prev) => !prev)}
>
{label ? `${label}: ${valueStr}` : valueStr}
{pickerContext.label ? `${pickerContext.label}: ${valueStr}` : valueStr}
</Button>
);
}
Expand Down
21 changes: 8 additions & 13 deletions docs/data/date-pickers/custom-field/BrowserV7Field.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content
},
);

const BrowserDateField = React.forwardRef((props, ref) => {
function BrowserDateField(props) {
console.log('AA', props);
const fieldResponse = useDateField(props);

const {
Expand All @@ -52,8 +53,6 @@ const BrowserDateField = React.forwardRef((props, ref) => {
// Can be passed to the button that clears the value
onClear,
clearable,
// Can be used to render a custom label
label,
// Can be used to style the component
areAllSectionsEmpty,
disabled,
Expand All @@ -65,10 +64,10 @@ const BrowserDateField = React.forwardRef((props, ref) => {
} = fieldResponse;

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

return (
<BrowserFieldRoot ref={handleRef} {...other}>
<BrowserFieldRoot {...other} ref={handleRef}>
<BrowserFieldContent>
<PickersSectionList
elements={elements}
Expand All @@ -91,17 +90,13 @@ const BrowserDateField = React.forwardRef((props, ref) => {
</IconButton>
</BrowserFieldRoot>
);
});
}

const BrowserDatePicker = React.forwardRef((props, ref) => {
function BrowserDatePicker(props) {
return (
<DatePicker
ref={ref}
{...props}
slots={{ field: BrowserDateField, ...props.slots }}
/>
<DatePicker {...props} slots={{ field: BrowserDateField, ...props.slots }} />
);
});
}

export default function BrowserV7Field() {
return (
Expand Down
140 changes: 65 additions & 75 deletions docs/data/date-pickers/custom-field/BrowserV7Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,91 +32,81 @@ const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content
},
);

const BrowserDateField = React.forwardRef(
(props: DatePickerFieldProps, ref: React.Ref<HTMLDivElement>) => {
const fieldResponse = useDateField<true, typeof props>(props);
function BrowserDateField(props: DatePickerFieldProps) {
JCQuintas marked this conversation as resolved.
Show resolved Hide resolved
console.log('AA', props);
flaviendelangle marked this conversation as resolved.
Show resolved Hide resolved
const fieldResponse = useDateField<true, typeof props>(props);

const {
// Should be ignored
enableAccessibleFieldDOMStructure,
const {
// Should be ignored
enableAccessibleFieldDOMStructure,

// Should be passed to the PickersSectionList component
elements,
sectionListRef,
contentEditable,
onFocus,
onBlur,
tabIndex,
onInput,
onPaste,
onKeyDown,
// Should be passed to the PickersSectionList component
elements,
sectionListRef,
contentEditable,
onFocus,
onBlur,
tabIndex,
onInput,
onPaste,
onKeyDown,

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

// Can be passed to a hidden <input /> element
onChange,
value,
// Can be passed to a hidden <input /> element
onChange,
value,

// Can be passed to the button that clears the value
onClear,
clearable,
// Can be passed to the button that clears the value
onClear,
clearable,

// Can be used to render a custom label
label,
// Can be used to style the component
areAllSectionsEmpty,
disabled,
readOnly,
focused,
error,

// Can be used to style the component
areAllSectionsEmpty,
disabled,
readOnly,
focused,
error,
// The rest can be passed to the root element
...other
} = fieldResponse;

// The rest can be passed to the root element
...other
} = fieldResponse;
const pickerContext = usePickerContext();
const handleRef = useForkRef(pickerContext.triggerRef, pickerContext.rootRef);

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

return (
<BrowserFieldRoot ref={handleRef} {...other}>
<BrowserFieldContent>
<PickersSectionList
elements={elements}
sectionListRef={sectionListRef}
contentEditable={contentEditable}
onFocus={onFocus}
onBlur={onBlur}
tabIndex={tabIndex}
onInput={onInput}
onPaste={onPaste}
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
<IconButton
onClick={() => pickerContext.setOpen((prev) => !prev)}
sx={{ marginLeft: 1.5 }}
aria-label={openPickerAriaLabel}
>
<CalendarIcon />
</IconButton>
</BrowserFieldRoot>
);
},
);
return (
<BrowserFieldRoot {...other} ref={handleRef}>
<BrowserFieldContent>
<PickersSectionList
elements={elements}
sectionListRef={sectionListRef}
contentEditable={contentEditable}
onFocus={onFocus}
onBlur={onBlur}
tabIndex={tabIndex}
onInput={onInput}
onPaste={onPaste}
onKeyDown={onKeyDown}
/>
</BrowserFieldContent>
<IconButton
onClick={() => pickerContext.setOpen((prev) => !prev)}
sx={{ marginLeft: 1.5 }}
aria-label={openPickerAriaLabel}
>
<CalendarIcon />
</IconButton>
</BrowserFieldRoot>
);
}

const BrowserDatePicker = React.forwardRef(
(props: DatePickerProps, ref: React.Ref<HTMLDivElement>) => {
return (
<DatePicker
ref={ref}
{...props}
slots={{ field: BrowserDateField, ...props.slots }}
/>
);
},
);
function BrowserDatePicker(props: DatePickerProps) {
return (
<DatePicker {...props} slots={{ field: BrowserDateField, ...props.slots }} />
);
}

export default function BrowserV7Field() {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from 'react';
import useForkRef from '@mui/utils/useForkRef';
import useSlotProps from '@mui/utils/useSlotProps';
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';
import { useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import { usePickerContext, useSplitFieldProps } from '@mui/x-date-pickers/hooks';
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers';
import { unstable_useMultiInputRangeField as useMultiInputRangeField } from '@mui/x-date-pickers-pro/hooks';
Expand All @@ -26,7 +25,7 @@ const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content
},
);

const BrowserTextField = React.forwardRef((props, ref) => {
function BrowserTextField(props) {
const {
// Should be ignored
enableAccessibleFieldDOMStructure,
Expand All @@ -43,23 +42,19 @@ const BrowserTextField = React.forwardRef((props, ref) => {
// Can be passed to a hidden <input /> element
onChange,
value,
// Can be used to render a custom label
label,
// Can be used to style the component
areAllSectionsEmpty,
disabled,
readOnly,
focused,
error,
InputProps: { ref: InputPropsRef, startAdornment, endAdornment } = {},
InputProps: { ref, startAdornment, endAdornment } = {},
// The rest can be passed to the root element
...other
} = props;

const handleRef = useForkRef(InputPropsRef, ref);

return (
<BrowserFieldRoot ref={handleRef} {...other}>
<BrowserFieldRoot {...other} ref={ref}>
{startAdornment}
<BrowserFieldContent>
<PickersSectionList
Expand All @@ -77,12 +72,13 @@ const BrowserTextField = React.forwardRef((props, ref) => {
{endAdornment}
</BrowserFieldRoot>
);
});
}

const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
function BrowserMultiInputDateRangeField(props) {
const pickerContext = usePickerContext();
const manager = useDateRangeManager();
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { slotProps, ownerState, ...otherForwardedProps } = forwardedProps;
const { slotProps, ...otherForwardedProps } = forwardedProps;

const startTextFieldProps = useSlotProps({
elementType: 'input',
Expand All @@ -105,7 +101,7 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {

return (
<Stack
ref={ref}
ref={pickerContext.rootRef}
spacing={2}
direction="row"
overflow="auto"
Expand All @@ -116,17 +112,16 @@ const BrowserMultiInputDateRangeField = React.forwardRef((props, ref) => {
<BrowserTextField {...fieldResponse.endDate} />
</Stack>
);
});
}

const BrowserDateRangePicker = React.forwardRef((props, ref) => {
function BrowserDateRangePicker(props) {
return (
<DateRangePicker
ref={ref}
{...props}
slots={{ ...props.slots, field: BrowserMultiInputDateRangeField }}
/>
);
});
}

export default function BrowserV7MultiInputRangeField() {
return (
Expand Down
Loading
Loading