Mui Popover открывается в неправильном месте

По документацию я должен нажимать на Смену и popover должен открываться рядом с ней.
import React from 'react';
import { Styled, titleStyleCSS } from './PopoverShift.styled';
import { Grid, Popover, Typography } from '@mui/material';
import { SvgCloseIcon } from '../../IconComponents/SvgCloseIcon';
type Props = {
handleClose: () => void;
open: boolean;
title: string;
anchorEl: null | undefined;
};
export const MuiPopover: React.FC<Props> = ({ handleClose, title, open, children, anchorEl }) => {
return (
<Popover
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<Styled.Root>
<Grid container spacing={2} justifyContent="space-between">
<Grid item xs={10}>
<Typography css={titleStyleCSS}>{title}</Typography>
</Grid>
<Grid item xs={2}>
<Styled.CloseButton aria-label="close" onClick={handleClose} color="primary">
<SvgCloseIcon />
</Styled.CloseButton>
</Grid>
</Grid>
<Styled.Content>{children}</Styled.Content>
</Styled.Root>
</Popover>
);
};
Код компонента Смены
import React, { createRef, useCallback, useMemo, useRef, useState } from 'react';
import GridLayout from 'react-grid-layout';
import { CalendarEventType } from '../types';
import {
Styled,
gridLayoutCSS,
eventTitleCSS,
eventTimeCSS,
eventMiniTitleCSS,
eventMiniTimeCSS,
eventMiniHoursCSS,
eventHoursCSS,
eventMiddleTitleCSS,
eventMiddleTimeCSS,
eventMiddleHoursCSS,
eventMiniShiftCSS,
timePickerCSS,
timePickerTwoCSS,
} from './CalendarDayItem.styled';
import '../../../../../../node_modules/react-grid-layout/css/styles.css';
import '../../../../../../node_modules/react-resizable/css/styles.css';
import { makeNumberedArray } from '../../../../../common/helpers';
import { TableRow } from '../CalendarDayItemTableRow';
import { format } from 'date-fns/esm';
import { Box, Button, Grid, TextField, Typography } from '@mui/material';
import { ml, mt } from '../../../../../common/common.styled';
import { MuiPopover } from '../../../../../common/newUi/MuiPopover';
import { useCalendarOneDayCtx } from '../../containers/CalendarOneDayCtx';
import { TimePicker } from '@mui/lab';
import { yup } from '../../../../core';
import { yupResolver } from '@hookform/resolvers/yup';
import { deleteButtonCSS, titleShiftCSS } from '../../../../../common/newUi/MuiPopover/PopoverShift.styled';
import { Controller, useForm } from 'react-hook-form';
import ReactGridLayout from 'react-grid-layout';
import { toast } from 'react-toastify';
import rfdc from 'rfdc';
import { v4 } from 'uuid';
const clone = rfdc();
type Props = {
events: CalendarEventType[];
segment: number;
};
type ShiftData = {
start: unknown;
end: unknown;
};
const defaultValues = {
start: new Date(),
end: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate(), 12, 0),
};
const schema = yup.object().shape({
start: yup.date().required(''),
end: yup.date().required(''),
});
type Popover = 'UPDATE';
const HOUR_COEFFICIENT = 5;
const MINUTES_SECTION = 15;
const allDayHrs = makeNumberedArray(24);
export const CalendarDayItem: React.FC<Props> = ({ events, segment }) => {
const [isDragging, setIsDragging] = useState(false);
const { onChange } = useCalendarOneDayCtx();
const [layout, setLayout] = useState<ReactGridLayout.Layout[]>();
const [anchorEl, setAnchorEl] = React.useState(null);
const eventsRef = useRef(events.map(() => createRef()));
const {
handleSubmit,
control,
reset,
formState: { errors },
} = useForm<ShiftData>({ defaultValues, resolver: yupResolver(schema) });
const formatToStringDateFormat = (amount: number): string => {
let minutesFromAmount = Math.trunc((amount % HOUR_COEFFICIENT) * MINUTES_SECTION);
minutesFromAmount = minutesFromAmount === 0 ? minutesFromAmount : minutesFromAmount - 15;
const minutes = minutesFromAmount.toString().padStart(2, '0');
const hours = Math.trunc(amount / HOUR_COEFFICIENT)
.toString()
.padStart(2, '0');
return `${hours}:${minutes}`;
};
const handleLayoutChange = useCallback(
(nextLayout: ReactGridLayout.Layout[]) => {
const newLayout = clone(nextLayout).map((item) => {
const offset = (item.y + item.h) % HOUR_COEFFICIENT;
// offsets in 15 minutes intervals
if (offset === 1) {
return { ...item, h: Math.trunc(item.h / HOUR_COEFFICIENT) * HOUR_COEFFICIENT };
}
return item;
});
newLayout?.forEach(({ i: layoutId, ...nextLayoutEl }) => {
const currLayoutEl = layout?.find((el) => el.i === layoutId);
if (!currLayoutEl) return;
if (currLayoutEl.h !== nextLayoutEl.h || currLayoutEl.y !== nextLayoutEl.y) {
onChange({
action: 'UPDATE',
id: layoutId.split(':')[0],
start: formatToStringDateFormat(nextLayoutEl.y),
end: formatToStringDateFormat(nextLayoutEl.y + nextLayoutEl.h),
segment,
name: layoutId.split(':')[1],
});
}
});
setLayout(nextLayout);
setLayout(newLayout);
},
[layout, onChange],
);
const getYAxisOffset = useCallback((timestamp: number) => {
const minutes = new Date(timestamp).getMinutes();
const hours = new Date(timestamp).getHours();
const returnValue =
hours * HOUR_COEFFICIENT + (minutes >= 15 ? Math.trunc(minutes / 15) * (HOUR_COEFFICIENT / 4) : 0);
return Number(returnValue);
}, []);
const blockedHours = useMemo(
() =>
events?.map((event) => [
getYAxisOffset(event.start) / HOUR_COEFFICIENT,
getYAxisOffset(event.end) / HOUR_COEFFICIENT,
]),
[events, getYAxisOffset],
);
const handleDragStart = useCallback(() => {
setIsDragging(true);
}, [setIsDragging]);
const handleDragStop = useCallback(() => {
setIsDragging(true);
}, [blockedHours]);
const handleOpenPopover = (e) => {
// e.preventDefault();
setAnchorEl(eventsRef.current);
};
const handleCloseModal = handleSubmit((data: ShiftData) => {
setAnchorEl(null);
});
const getIsHourBlocked = useCallback(
(hour: number) => blockedHours?.some(([startHour, endHour]) => startHour <= hour && endHour > hour),
[blockedHours],
);
const handleCreateShift = useCallback(
(start: number, end: number) => {
onChange({ action: 'CREATE', start, end, name: 'Новая смена', segment, id: v4() });
toast.success('Смена успешно создана');
},
[onChange, segment],
);
const handleDeleteShift = useCallback(
(id: string) => (e) => {
e.preventDefault();
onChange({ action: 'DELETE', id: id.split(':')[0] });
},
[onChange],
);
return (
<Styled.Root>
<Styled.Background>
<Styled.Table>
<tbody>
{allDayHrs?.map((hour) => (
<TableRow
onCreateNewShift={handleCreateShift}
isBlocked={isDragging || getIsHourBlocked(hour)}
hour={hour}
key={hour}
/>
))}
</tbody>
</Styled.Table>
</Styled.Background>
<GridLayout
css={gridLayoutCSS}
layout={layout}
className="layout"
isBounded
cols={24}
rowHeight={2.5}
width={269}
onLayoutChange={handleLayoutChange}
onResizeStart={handleDragStart}
onResizeStop={handleDragStop}
onDragStart={handleDragStart}
onDragStop={handleDragStop}
// breakpoints={{ xxl: 1920, lg: 1280, md: 960, sm: 600, xs: 0 }}
// cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
>
{events?.map((event, index) => {
return (
<Styled.Event
key={`${event.id}:${event.name}`}
ref={eventsRef.current[index]}
onClick={handleOpenPopover}
data-grid={{
x: 0,
y: getYAxisOffset(event.start),
w: 24,
h: getYAxisOffset(event.end) - getYAxisOffset(event.start),
minW: 24,
maxW: 24,
isDraggable: true,
isResizable: true,
static: true,
isBounded: true,
}}
>
{renderShifts(event)}
<MuiPopover
handleClose={handleCloseModal}
open={Boolean(anchorEl)}
title={event.name}
anchorEl={anchorEl}
>
<form onSubmit={handleCloseModal}>
<Grid container spacing={2} justifyContent="space-between">
<Grid item xs={8}>
<Typography css={titleShiftCSS}>Смена</Typography>
</Grid>
<Grid item xs={4}>
<Typography>Название</Typography>
</Grid>
</Grid>
<Grid
css={mt(18)}
container
justifyContent="space-between"
columns={2}
alignItems="center"
flexWrap="nowrap"
>
<Grid item xs={8}>
<Typography css={titleShiftCSS}>Часы работы:</Typography>
</Grid>
<Grid item xs={4} display="flex">
<Grid display="flex" alignItems="center">
<Typography>с</Typography>
<Grid css={timePickerCSS}>
<Controller
control={control}
name="start"
render={({ field: { value, onChange } }) => (
<TimePicker
disableOpenPicker={true}
ampm={false}
onChange={onChange}
value={value ? event.start : null}
renderInput={(params) => (
<TextField
error={Boolean(errors.start?.message)}
helperText={Boolean(errors.start?.message) && 'Неправильное время '}
{...params}
/>
)}
/>
)}
/>
</Grid>
</Grid>
<Grid css={timePickerTwoCSS} display="flex" alignItems="center">
<Typography>-</Typography>
<Controller
control={control}
name="end"
render={({ field: { value, onChange } }) => (
<TimePicker
disableOpenPicker={true}
ampm={false}
onChange={onChange}
value={value ? event.end : null}
renderInput={(params) => (
<TextField
error={Boolean(errors.end?.message)}
helperText={Boolean(errors.end?.message) && 'Неправильное время '}
{...params}
/>
)}
/>
)}
/>
</Grid>
</Grid>
</Grid>
<Box onClick={handleDeleteShift(event.id)} css={deleteButtonCSS}>
Удалить
</Box>
</form>
</MuiPopover>
</Styled.Event>
);
})}
</GridLayout>
</Styled.Root>
);
};