Ну вот наконец-то и ответ... Мы будем использовать Zoom
transition и для его props
мы можем передать style
и изменить для него transfromOrigin
в котором будут содержаться координаты, откуда должна начинаться анимация.
Координаты мы можем получить при клике на кнопку с помощью:
const rect = event.currentTarget.getBoundingClientRect();
В rect.left
, rect.top
находятся координаты левого верхнего угла элемента. Чтобы получить центр элемента нужно прибавить rect.width / 2
и rect.height / 2
.

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 можно было запустить - отредактируйте и спасибо вам)