在桌面 MUI 5 DatePicker 中打开 Dialog 而不是 Popper

Lan*_*tor 3 reactjs material-ui

我希望 MUI v5 DatePicker(@mui/lab 5.0.0-alpha-51) 的行为类似于DesktopDatePicker(允许直接编辑文本框中的日期)。但是,当单击日历图标时,我想打开选择器对话框,就像单击MobileDatePicker.

我尝试使用MobileDatePicker并添加endAdornment到 来InputProps绘制日历图标。但这不起作用。

也许更清楚地说:我希望当用户单击日历图标时DesktopDatePicker打开对话框。MobileDatePicker

有没有办法实现这种混合行为?

Nea*_*arl 6

如果您查看MobileWrapperDesktopWrapper定义,您会发现它们使用不同的组件来显示选择器(前者使用模态,后者使用弹出窗口),并且无法使用选择器组件提供的道具来交换它,但你也知道内部模态来自哪里,所以你可以抓住它:

import PickersModalDialog from "@mui/lab/internal/pickers/PickersModalDialog";
Run Code Online (Sandbox Code Playgroud)

在本中,您可以看到 MUI 公开了使用桌面和移动选择器StaticDatePicker使用的内部Picker组件,如果您想构建自己的自定义弹出窗口/模式,这正是您想要的,所以抓住这个也:

import StaticDatePicker from '@mui/lab/StaticDatePicker';
Run Code Online (Sandbox Code Playgroud)

下一步是集成并使它们一起工作,我们有 ,DesktopDatePicker因为您想要编辑TextField, 以便在模式中PickersModalDialog显示。StaticDatePicker为此,您需要执行以下操作:

  • (1)禁用弹出框选择器,否则DesktopDatePicker我们将同时显示 2 个选择器。
  • (2)控制DesktopDatePicker日期值。当DesktopDatePicker用户编辑TextField.
  • (3)控制StaticDatePicker日期值。StaticDatePicker当用户在模式中选择日期时更改值的请求。
  • (4)PickersModalDialog通过覆盖下面步骤中的 props 来控制打开状态。
  • (5)在 中添加所需的道具PickersModalDialog
    • onAccept:当用户单击“确定”按钮时。
    • onClear:当用户单击取消按钮时。
    • onSetToday:当用户单击“今天”按钮时。仅在 中可用MobileDatePicker,如果要显示,请showTodayButton在 中设置PickersModalDialog
    • onDismiss:当对话框想要自行关闭时(例如当用户在模态框之外单击时)

将它们放在一起,我们将得到如下所示的内容:

const [value, setValue] = React.useState<Date | null>(() => new Date()); // (2)
const [tempValue, setTempValue] = React.useState<Date | null>(null); // (3)
const [open, setOpen] = React.useState(false); // (4)

return (
  <>
    <DesktopDatePicker
      label="For desktop"
      value={value}
      open={false} // (1)
      onChange={(newValue) => setValue(newValue)}
      onOpen={() => {
        setTempValue(value);
        setOpen(true);
      }}
      renderInput={(params) => <TextField {...params} />}
    />
    <PickersModalDialog
      showTodayButton
      open={open}
      // (5)
      onAccept={() => {
        setValue(tempValue);
        setOpen(false);
      }}
      onSetToday={() => {
        setValue(new Date());
        setOpen(false);
      }}
      onDismiss={() => setOpen(false)}
      onClear={() => setOpen(false)}
    >
      <StaticDatePicker
        displayStaticWrapperAs="mobile"
        value={tempValue}
        onChange={(newValue) => setTempValue(newValue)}
        renderInput={(params) => <TextField {...params} />}
      />
    </PickersModalDialog>
  </>
);
Run Code Online (Sandbox Code Playgroud)

现场演示

Codesandbox 演示