/** @jsxRuntime classic */ /** @jsx jsx */ import { FC, useEffect, useMemo, useRef, useState, MutableRefObject, } from 'react'; import { jsx } from '@emotion/react'; import { useDraggable } from '@dnd-kit/core'; import dayjs from 'dayjs'; import { calculateMarginFromMinutes, calculateMinutesFromHeight, } from '../../utils/timeUtils'; import { useMiddlewareContext } from '../../hooks/useMiddlewareContext'; import { useDebouncedValue } from '../../hooks/useDebouncedValue'; import { useResize } from '../../hooks/useResize'; import { IDraggableDayToDropProps } from '../../types'; import { draggableContainer, draggableContent, draggableHandler, draggableResizeHandler, } from '../styles'; import { DndIcon } from '../../utils/DndIcon'; import { getMinutesDifferenceByStep } from '../../utils'; export const Draggable: FC = ({ children, id, state, parentId, groupTop, groupCount, groupIndex, }) => { const elementId = `draggable-${id}`; const { updateDatesRange, getTopAndHeight, options } = useMiddlewareContext(); const { top, height } = useMemo( () => getTopAndHeight( dayjs.utc(state.startDate).toDate().getTime(), dayjs.utc(state.endDate).toDate().getTime() ), [state.startDate, state.endDate] ); const { isDragging, setNodeRef, listeners } = useDraggable({ id: String(id), data: { parentId: parentId, event: state, }, }); const ref = useRef() as MutableRefObject; const { initResize, size, cursor } = useResize( ref as MutableRefObject, { axis: 'vertical', } ); const sizeH = useDebouncedValue(size.height, 200); const [sizeHeight, setSizeHeight] = useState(size.height); useEffect(() => { setSizeHeight(sizeH); }, [sizeH]); const handleResize = () => { const draggableElement = ref?.current; if (!isDragging && draggableElement && !Number.isNaN(sizeHeight)) { const draggableHeight = draggableElement.offsetHeight; if (draggableHeight !== sizeHeight) return; const startDate = state?.startDate; let minutes = Math.floor(calculateMinutesFromHeight(draggableHeight)); minutes = getMinutesDifferenceByStep( startDate, minutes, options.dndStepLength, true ); const endDate = dayjs .utc(startDate) .add(minutes, 'minute') .set('milliseconds', 0) .set('seconds', 0) .toISOString(); const onChangeData = { type: 'SLOT_RESIZE', data: { startDate, endDate, startTime: dayjs.utc(startDate).format('HH:mm'), endTime: dayjs.utc(endDate).format('HH:mm'), parentId, slotId: String(state.id), }, }; draggableElement.removeAttribute('style'); setSizeHeight(calculateMarginFromMinutes(minutes)); updateDatesRange(state.id, startDate, endDate, onChangeData); } }; useEffect(() => { handleResize(); }, [sizeHeight]); return (
{children} {options.dragAndDrop && (
)} {options.resize && (
)}
); };