【问题标题】:MUI 5 + HeadlessUI: Can't close <DatePicker /> inside <Dialog />MUI 5 + HeadlessUI:无法在 <Dialog /> 内关闭 <DatePicker />
【发布时间】:2022-07-27 20:14:39
【问题描述】:

我将 HeadlessUI 与 MUI 5 结合使用,并面临一个问题,即在 HeadlessUI 的 &lt;Dialog /&gt; 组件中使用 &lt;DatePicker /&gt; 日期选择弹出器时无法关闭它。当我单击弹出器之外但在模式内的任何位置时,弹出器应该关闭。

我尝试使用 MUI 的 &lt;ClickAwayListener /&gt; 并使用 PopperProps={{ disablePortal: true }} 将 popper 设置为在 &lt;Dialog /&gt; 内呈现,但均未成功。也许我遗漏了一些明显的东西?

import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
import TextField from "@mui/material/TextField";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import DatePicker from "@mui/lab/DatePicker";

export default function MyModal() {
  let [isOpen, setIsOpen] = useState(true);
  const [value, setValue] = useState(null);

  function closeModal() {
    setIsOpen(false);
  }

  function openModal() {
    setIsOpen(true);
  }

  return (
    <>
      <div className="fixed inset-0 flex items-center justify-center">
        <button
          type="button"
          onClick={openModal}
          className="px-4 py-2 text-sm font-medium text-white bg-black rounded-md bg-opacity-20 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
        >
          Open dialog
        </button>
      </div>

      <Transition appear show={isOpen} as={Fragment}>
        <Dialog
          as="div"
          className="fixed inset-0 z-10 overflow-y-auto"
          onClose={() => {}}
        >
          <div className="min-h-screen px-4 text-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0"
              enterTo="opacity-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100"
              leaveTo="opacity-0"
            >
              <Dialog.Overlay className="fixed inset-0" />
            </Transition.Child>

            {/* This element is to trick the browser into centering the modal contents. */}
            <span
              className="inline-block h-screen align-middle"
              aria-hidden="true"
            >
              &#8203;
            </span>
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <div className="inline-block w-full max-w-md p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl">
                <Dialog.Title
                  as="h3"
                  className="text-lg font-medium leading-6 text-gray-900"
                >
                  Payment successful
                </Dialog.Title>
                <div className="mt-2">
                  <LocalizationProvider dateAdapter={AdapterDateFns}>
                    <DatePicker
                      label="Basic example"
                      value={value}
                      onChange={(newValue) => {
                        setValue(newValue);
                      }}
                      renderInput={(params) => <TextField {...params} />}
                    />
                  </LocalizationProvider>
                </div>

                <div className="mt-4">
                  <button
                    type="button"
                    className="inline-flex justify-center px-4 py-2 text-sm font-medium text-blue-900 bg-blue-100 border border-transparent rounded-md hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500"
                    onClick={closeModal}
                  >
                    Got it, thanks!
                  </button>
                </div>
              </div>
            </Transition.Child>
          </div>
        </Dialog>
      </Transition>
    </>
  );
}

【问题讨论】:

    标签: reactjs material-ui tailwind-css headless-ui


    【解决方案1】:

    我在使用 @headlessui 的对话框时遇到了同样的问题,但后来以 Slider Over 的方式。

    我已经用 MUI Drawer 替换了我的 @headlessui 对话框,我可以毫无问题地打开和关闭 Datepicker。

    以你的为例,这是我如何做到这一点的一个例子:

    import { useState } from "react";
    import DialogTitle from "@mui/material/DialogTitle";
    import Dialog from "@mui/material/Dialog";
    import TextField from "@mui/material/TextField";
    import AdapterDateFns from "@mui/lab/AdapterDateFns";
    import LocalizationProvider from "@mui/lab/LocalizationProvider";
    import DatePicker from "@mui/lab/DatePicker";
    
    export default function MyModal() {
      let [isOpen, setIsOpen] = useState(true);
      const [value, setValue] = useState(null);
    
      function closeModal() {
        setIsOpen(false);
      }
    
      function openModal() {
        setIsOpen(true);
      }
    
      return (
        <>
          <div className="fixed inset-0 flex items-center justify-center">
            <button
              type="button"
              onClick={openModal}
              className="px-4 py-2 text-sm font-medium text-white bg-black rounded-md bg-opacity-20 hover:bg-opacity-30 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75"
            >
              Open dialog
            </button>
          </div>
    
          <Dialog onClose={closeModal} open={isOpen}>
            <DialogTitle className="text-lg font-medium leading-6 text-gray-900">
              Payment successful
            </DialogTitle>
            <div className="p-6 my-8 overflow-hidden text-left align-middle bg-white w-96 h-96">
              <div className="mt-2">
                <LocalizationProvider dateAdapter={AdapterDateFns}>
                  <DatePicker
                    label="Basic example"
                    value={value}
                    onChange={(newValue) => {
                      setValue(newValue);
                    }}
                    renderInput={(params) => <TextField {...params} />}
                  />
                </LocalizationProvider>
              </div>
    
              <div className="mt-4">
                <button
                  type="button"
                  className="inline-flex justify-center px-4 py-2 text-sm font-medium text-blue-900 bg-blue-100 border border-transparent rounded-md"
                  onClick={closeModal}
                >
                  Got it, thanks!
                </button>
              </div>
            </div>
          </Dialog>
        </>
      );
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2021-01-09
      • 2022-07-09
      • 2021-07-16
      • 2022-10-30
      • 2022-07-27
      • 2021-12-03
      相关资源
      最近更新 更多