Модальное/диалоговое окно всплывающее из кнопки/элемента

Рейтинг: 0Ответов: 1Опубликовано: 07.02.2023

Есть задача, где необходимо показать модальное окно, будто всплывающее из кнопки (в конечном результате отображается, по центру экрана), есть ли какие-то готовые реализации данного функционала в MUI или сторонние решение и если нет, то как подобное можно реализовать?

Подойдет анимация появления/закрытия как в MacOS: введите сюда описание изображения

Ответы

▲ 0Принят

Ну вот наконец-то и ответ... Мы будем использовать Zoom transition и для его props мы можем передать style и изменить для него transfromOrigin в котором будут содержаться координаты, откуда должна начинаться анимация.

Координаты мы можем получить при клике на кнопку с помощью:

const rect = event.currentTarget.getBoundingClientRect();

В rect.left, rect.top находятся координаты левого верхнего угла элемента. Чтобы получить центр элемента нужно прибавить rect.width / 2 и rect.height / 2.


Edit dialog-show-animation

import { Dialog, Zoom, DialogTitle, DialogContent } from "@mui/material";
import { useState } from "react";

function DialogTest()
{
    const [ isDialogOpen, setIsDialogOpen ] = useState<boolean>(false);
    const [ clickPosition, setClickPosition ] = useState<{ x: number, y: number; }>({ x: 0, y: 0 });

    return (
        <>
            <button
                onClick={(event) =>
                {
                    const rect = event.currentTarget.getBoundingClientRect();

                    setClickPosition({
                        x: rect.left + rect.width / 2,
                        y: rect.top + rect.height / 2
                    });

                    setIsDialogOpen(true);
                }}
            >
                Test button
            </button>

            <Dialog
                open={isDialogOpen}
                onClose={() => setIsDialogOpen(false)}
                slots={{ transition: Zoom }}
                slotProps={{
                    transition:
                    {
                        style: { transformOrigin: `${ clickPosition.x }px ${ clickPosition.y }px` }
                    }
                }}
            >
                <DialogTitle>
                    Modal title
                </DialogTitle>

                <DialogContent>
                    Lorem ipsum dolor sit amet consectetur.
                </DialogContent>
            </Dialog>
        </>
    );
}

export default DialogTest;

(если кто-то может сделать так, чтобы прямо на SO можно было запустить - отредактируйте и спасибо вам)