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>
      );
    };



Ответы (0 шт):