Open flaviendelangle opened 1 week ago
WIP
The content below is purely theoretical for now and aims at discussing what the DX could look like to build custom field in 12-18 months and how it could help us decrease the complexity of our codebase.
It takes for granted that we don't support @mui/material/TextField
anymore and aims at solving the following problem:
import { DateField } from '@mui/x-date-pickers/DateField'
)useField
behind the scene)AutoComplete
, use a maksed-based approach, ...)PickersField
componentThis new component would follow the DX of Base UI and would be the cornerstone to build a field that uses our editing behaviors. It would be used to create DateField
, TimeField
, SingleInputDateRangeField
, etc... and would also be used for people that want to create a field with a custom UI while using our editing behaviors (see this demo to have the current DX).
In short, it would replace both PickersTextField
and the useDateField
(and equivalent) hook.
Here is a simplified version of what the equivalent of the current DateField
component could look like:
import * as PickersField from '@mui/x-date-pickers/base'
import * as Field from '@base_ui/react/Field';
// This replaces the current `useDateField` hook
// and allow `PickersField.Root` to directly call `useField` with the right params
const dateFieldController: PickersField.Controller = {
valueManager: singleItemValueManager,
fieldValueManager: singleItemFieldValueManager,
valueType: 'date',
validate: validateDate,
}
const DateField = (props: DateFieldProps) => {
const { label } = props
return (
<PickersField.Root controller={dateFieldController}>
<Field.Label>{label}</Field.Label>
<PickersField.SectionsContainer>
{({ element }) => (
<PickersField.Section element={element} />
)}
</PickersField.SectionsContainer>
<Field.Error show="customError />
</PickersField.Root>
)
}
import TextField from '@mui/material/TextField';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { useValidation, validateDate } from '@mui/x-date-pickers/validation';
import { useSplitFieldProps, useFieldPlaceholder } from '@mui/x-date-pickers/hooks';
function ReadonlyDateField(props) {
const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date');
const { value, timezone, format, onOpen } = internalProps;
const placeholder = useFieldPlaceholder(internalProps);
const { hasValidationError } = useValidation({
validator: validateDate,
value,
timezone,
props: internalProps,
});
return (
<TextField
{...forwardedProps}
value={value == null ? '' : value.format(format)}
placeholder={placeholder}
// TODO: Once the pickers no longer return the `InputProps`,
// we will also have to add the icon manually here.
// And we should migrate to slots in the doc when we can, to be future proof.
InputProps={{ ...forwardedProps.InputProps, readOnly: true }}
error={hasValidationError}
onClick={onOpen}
/>
);
}
function ReadonlyFieldDatePicker(props) {
return (
<DatePicker slots={{ ...props.slots, field: ReadonlyDateField }} {...props} />
);
}
We currently have a several examples on how to create fields with custom UIs (using browser primitives, using Joy UI, ...) and we have 2 demos on how to create fields with custom behaviors (one with a Button, one with an Autocomplete).
The goal of this issue is to improve the 2nd type of demo and to create a few new ones.
Here are the planned work:
Enhancements
14495
14515
InputProps.endAdornment
) and instead pass a prop likeonOpen
to the field component and let him handle the opening UI (the built-in fields would then handle slots likeopeningButton
,openingIcon
andinputAdornment
themselves)Missing doc sections
useValidation
Recipes for custom behavior field
14494
12342
Search keywords: