我想编写一个返回 MUI DatePicker 的 React TS 组件,但每当我选择新日期时,我都希望在值字段中显示一个自定义组件(称为
<Badge>
)。
我已经用 MUI Select 完成了:
return (
<div css={styles.wrapper}>
<MaterialSelect
value={value || ''}
renderValue={(selected) => {
if (selected === '' && placeholder) {
return <span css={styles.placeholder}>{placeholder}</span>;
}
return (
<Badge
customText={placeholder}
/>
);
}}
>
{options.map((option) => (
<MenuItem value={option.value} key={option.value}>
{option.label}
</MenuItem>
))}
</MaterialSelect>
</div>
);
};
但是在 MUIDatePicker (来自 @mui/x-date-pickers/DatePicker)中,我无法使用 renderValue,编辑我找到的字段的唯一方法是使用 slot 和 slotprops。我尝试了不同的方法,例如:
return (
<LocalizationProvider dateAdapter={AdapterMoment}>
<MUIDatePicker
label={label}
value={dateValue}
open={open}
onClose={closePicker}
onOpen={openPicker}
onChange={handleChange}
css={styles.root}
views={yearOnly ? ['year'] : ['year', 'day']}
slotProps={{
textField: {
value: <Badge type={BadgeType.DELAYED} customText="Test" />,
},
}}
/>
</LocalizationProvider>
);
但这实际上改变了字段的值,我想将值保留为 dateValue。在 slot、slotprops 或我能找到的任何其他地方也没有 renderValue。有什么办法可以让它发挥作用吗?
我没有解决我的问题,但现在我使用 startAdornment 来渲染组件并将文本字段的值设置为显示:无。组件现在返回:
<LocalizationProvider dateAdapter={AdapterMoment}>
<MUIDatePicker
value={dateValue}
open={open}
onClose={closePicker}
onOpen={openPicker}
onChange={handleChange}
css={styles.root}
views={yearOnly ? ['year'] : ['year', 'day']}
slotProps={{
textField: {
placeholder,
error,
InputProps: {
startAdornment: value && (
<Badge
type={BadgeType.IN_PROGRESS}
customText={`${placeholder}: ${value}`}
customStyles={styles.filterBadge}
/>
),
},
},
}}
/>
{!isFilterField && <FormHelperText>{helperText}</FormHelperText>}
</LocalizationProvider>
我想显示选择的日期是哪一周(周六至周日),并最终使用@Axels 作为灵感。
我没有看到@Axel的解决方案如何隐藏内置文本字段,所以我最终朝类似的方向前进,但我只是完全隐藏日期选择器文本字段,并在其位置使用单独的文本字段,单击它会打开选取器。
然后只需根据所选日期设置文本字段值(对于我的用例来说,该值始终是给定周的星期日:
const WeekPicker = props => {
const [date, setDate] = React.useState(moment());
const [open, setOpen] = React.useState(false);
const [displayWeek, setDisplayWeek] = React.useState('');
React.useEffect(() => {
const startOfWeek = date.clone().startOf('week');
const endOfWeek = date.clone().endOf('week');
setDisplayWeek(
`${startOfWeek.format('MM/DD/YYYY')} - ${endOfWeek.format('MM/DD/YYYY')}`,
);
}, [date]);
return (
<Box>
<DatePicker
value={date}
open={open}
onClose={() => {
setOpen(false);
}}
onChange={newDate => setDate(newDate.endOf('week'))}
slotProps={{
textField: {
sx: { maxWidth: 0 },
InputProps: { endAdornment: null },
},
}}
/>
<TextField
value={displayWeek}
onClick={() => {
setOpen(true);
}}
InputProps={{
startAdornment: <CalendarTodayIcon />,
}}
/>
</Box>
);
};