Skip to content
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
'use client';
import * as React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { useFormControl } from '@mui/material/FormControl';
import { styled, useThemeProps } from '@mui/material/styles';
import useForkRef from '@mui/utils/useForkRef';
import refType from '@mui/utils/refType';
import composeClasses from '@mui/utils/composeClasses';
import capitalize from '@mui/utils/capitalize';
import useSlotProps from '@mui/utils/useSlotProps';
import resolveComponentProps from '@mui/utils/resolveComponentProps';
import visuallyHidden from '@mui/utils/visuallyHidden';
import { MuiEvent } from '@mui/x-internals/types';
import {
Expand All @@ -23,9 +25,24 @@ import {
Unstable_PickersSectionListSectionSeparator as PickersSectionListSectionSeparator,
Unstable_PickersSectionListSectionContent as PickersSectionListSectionContent,
PickersSectionElement,
PickersSectionListSlotProps,
} from '../../PickersSectionList';
import { usePickerTextFieldOwnerState } from '../usePickerTextFieldOwnerState';
import { PickerTextFieldOwnerState } from '../../models/fields';
import { PickerOwnerState } from '../../models/pickers';

function mergePickersInputBaseSectionContentSlotProps(
consumerSlotProps: PickersSectionListSlotProps['sectionContent'],
baseClassName: string,
): PickersSectionListSlotProps['sectionContent'] {
return (ownerState: PickerOwnerState) => {
const resolved = resolveComponentProps(consumerSlotProps, ownerState) ?? {};
return {
...resolved,
className: clsx(baseClassName, resolved.className),
};
};
}

const round = (value: number) => Math.round(value * 1e5) / 1e5;

Expand Down Expand Up @@ -444,7 +461,10 @@ const PickersInputBase = React.forwardRef(function PickersInputBase(
...slotProps?.input,
ownerState,
} as any,
sectionContent: { className: pickersInputBaseClasses.sectionContent },
sectionContent: mergePickersInputBaseSectionContentSlotProps(
slotProps?.sectionContent,
pickersInputBaseClasses.sectionContent,
),
sectionSeparator: ({ separatorPosition }) => ({
className:
separatorPosition === 'before'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { SxProps, Theme } from '@mui/material/styles';
import { MuiEvent } from '@mui/x-internals/types';
import { PickersSectionListProps } from '../../PickersSectionList';
import { PickersSectionListProps, PickersSectionListSlotProps } from '../../PickersSectionList';
import { PickerTextFieldOwnerState } from '../../models/fields';

export interface PickersInputPropsUsedByField extends Pick<
Expand Down Expand Up @@ -83,6 +83,11 @@ export interface PickersInputBaseSlotProps {
root?: PickersInputBaseRootSlotProps;
input?: PickersInputBaseInputSlotProps;
htmlInput?: React.ComponentPropsWithRef<'input'>;
/**
* Props forwarded to each section's content element inside `PickersSectionList`.
* Merged with the built-in section content styles.
*/
sectionContent?: PickersSectionListSlotProps['sectionContent'];
}

export interface PickersInputBaseProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,52 @@ describe('<PickersTextField /> - slot forwarding', () => {
expect(screen.getByTestId('html-input')).not.to.equal(null);
});

it('should merge `slotProps.input.slotProps.sectionContent` onto each section content element', () => {
render(
<PickersTextField
{...STUB_PROPS}
slotProps={{
input: {
slotProps: {
sectionContent: { 'data-testid': 'picker-section-content' } as any,
},
},
}}
/>,
);

const nodes = screen.getAllByTestId('picker-section-content');
expect(nodes.length).to.be.greaterThan(0);
nodes.forEach((node) => {
expect(node.className).to.include('MuiPickersInputBase-sectionContent');
});
});

it('should resolve a callback `slotProps.input.slotProps.sectionContent` and merge the result onto each section content element', () => {
render(
<PickersTextField
{...STUB_PROPS}
slotProps={{
input: {
slotProps: {
sectionContent: (() => ({
'data-testid': 'picker-section-content-fn',
className: 'custom-section-content',
})) as any,
},
},
}}
/>,
);

const nodes = screen.getAllByTestId('picker-section-content-fn');
expect(nodes.length).to.be.greaterThan(0);
nodes.forEach((node) => {
expect(node.className).to.include('MuiPickersInputBase-sectionContent');
expect(node.className).to.include('custom-section-content');
});
});

it('should forward `slotProps.inputLabel` to the label element', () => {
render(
<PickersTextField
Expand Down
Loading