Skip to content

[pickers] PickersTextField add support for slotProps #18006

Description

@MonstraG

Summary

I undrstand PickersTextField as a kind of special TextField to be used in Date/Time/DateTime inputs.

Normal TextField supports slotProps, and old pattern of inputProps, InputProps, SomethingElseProps is deprecated.

I, therefore, expect PickersTextField to accept slotProps.

Examples

N/A

Motivation

I have written and used a special wrapper around TextField, to use everywere.

This is the complete thing:

import type { TestId } from "../components/DataTestIdElements";
import type { RequireAtLeastOne } from "../types";
import TextField from "@mui/material/TextField";
import type { SxProps, Theme } from "@mui/material/styles";
import type { FilledTextFieldProps } from "@mui/material/TextField";
import { type FC, useMemo, memo } from "react";
import { InputHelperText } from "./InputHelperText";
import { mergeSlotProps } from "@mui/material/utils";

export type InputColorVariant = "gray" | "white";

interface Props extends TestId, Omit<FilledTextFieldProps, "variant"> {
	helperTextColor?: string;
	colorVariant?: InputColorVariant;
}

export type MyInputProps = RequireAtLeastOne<Props, "name" | "autoComplete" | "testId">;

export const grayInputVariantSx: SxProps<Theme> = {
     ...styles here
};

export const whiteInputVariantSx: SxProps<Theme> = {
     ...styles here
};

export const MyInput: FC<MyInputProps> = ({
	slotProps,
	helperText,
	testId,
	helperTextColor,
	colorVariant = "gray",
	InputProps,
	FormHelperTextProps,
	inputProps,
	...rest
}) => {
	const mergedSlotProps: FilledTextFieldProps["slotProps"] = useMemo(() => {
		return {
			...slotProps,
			input: mergeSlotProps(slotProps?.input, {
				...(InputProps as unknown as object), // https://github.com/mui/material-ui/issues/43573#issuecomment-2364189702, https://github.com/mui/material-ui/issues/45414
				disableUnderline: true,
				sx: colorVariant === "gray" ? grayInputVariantSx : whiteInputVariantSx
			}),
			formHelperText: mergeSlotProps(slotProps?.formHelperText, {
				...(FormHelperTextProps as unknown as object), // https://github.com/mui/material-ui/issues/43573#issuecomment-2364189702, https://github.com/mui/material-ui/issues/45414
				component: "div",
				sx: {
					...styles
				}
			}),
			htmlInput: mergeSlotProps(slotProps?.htmlInput, {
				...inputProps, // https://github.com/mui/material-ui/issues/43573#issuecomment-2364189702, https://github.com/mui/material-ui/issues/45414
				sx: {
					...styles
				}
			})
		};
	}, [FormHelperTextProps, InputProps, inputProps, slotProps, colorVariant]);

	return (
		<TextField
			fullWidth
			variant="filled"
			size="small"
			data-testid={`${testId || rest.name || rest.autoComplete}Input`}
			slotProps={mergedSlotProps}
			helperText={
				helperText ? (
					<InputHelperText sx={helperTextColor ? { color: helperTextColor } : undefined}>
						{helperText}
					</InputHelperText>
				) : undefined
			}
			{...rest}
		/>
	);
};

It's not ideal, and was born years ago, but it works, and is relatively simple. (InputProps/FormHelperTextProps/inputProps are only there because Autocomplete still uses them).

Before trying to upgrade to mui-x v8, I just used as is in the DatePicker and it just worked.

<DatePicker
	slots={{
		textField: MyInput
	}}
	slotProps={{
		textField: {
			helperText: <>My hint text</>
		}
	}}
/>

Now, I have to write a new MyPickersTextField that I need to keep in-sync with MyInput, but I just don't know how to do so, given that the original uses slotProps.

Right now I'll just use enableAccessibleFieldDOMStructure={false} but this will be deprecated soon, so I need a proper solution, or an example. I can sort of see how I would do it if MyPickersTextField had slotProps. Existing examples in docs use enableAccessibleFieldDOMStructure={false}.

Search keywords: PickersTextField, slotProps, inputProps, InputProps

Metadata

Metadata

Assignees

No one assigned

    Labels

    customization: domComponent's DOM customizability, e.g. slot.scope: pickersChanges related to the date/time pickers.type: new featureExpand the scope of the product to solve a new problem.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions