/** @jsxRuntime classic */ /** @jsx jsx */ import { FC, useEffect, useMemo, useRef, useState, MutableRefObject, } from 'react'; import { useDraggable } from '@dnd-kit/core'; import { jsx } from '@emotion/react'; import dayjs from 'dayjs'; import { calculateMarginLeftFromMinutes, calculateMinutesFromWidth, oneHourWidth, } from '../../../utils/timeUtils'; import { useMiddlewareContext } from '../../../hooks/useMiddlewareContext'; import { useDebouncedValue } from '../../../hooks/useDebouncedValue'; import { useResize } from '../../../hooks/useResize'; import { IDraggableDayToDropProps } from '../../../types'; import { draggableContainerHorizontal, draggableContentHorizontal, draggableHandler, draggableResizeHandler, } from '../../styles'; import { DndIcon } from '../../../utils/DndIcon'; import { getMinutesDifferenceByStep } from '../../../utils'; export const DraggableHorizontal: FC = ({ children, id, state, parentId, groupTop, groupCount, groupIndex, }) => { const elementId = `draggable-${id}`; const { updateDatesRange, getTopAndHeight, options, day: daysCount, } = useMiddlewareContext(); const { top, height } = useMemo( () => getTopAndHeight( dayjs.utc(state.startDate).toDate().getTime(), dayjs.utc(state.endDate).toDate().getTime(), true ), [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: 'horizontal', } ); const sizeW = useDebouncedValue(size.width, 200); const [sizeWidth, setSizeWidth] = useState(size.width); useEffect(() => { setSizeWidth(sizeW); }, [sizeW]); const handleResize = () => { const draggableElement = ref?.current; if (!isDragging && draggableElement && !Number.isNaN(sizeWidth)) { const draggableWidth = draggableElement.offsetWidth; if (draggableWidth !== sizeWidth) return; const startDate = state?.startDate; let minutes = Math.floor(calculateMinutesFromWidth(draggableWidth)); 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'); setSizeWidth(calculateMarginLeftFromMinutes(minutes)); updateDatesRange(state.id, startDate, endDate, onChangeData); } }; useEffect(() => { handleResize(); }, [sizeWidth]); if (top + height > oneHourWidth * 24 * daysCount + 6) return null; return (
{children} {options.dragAndDrop && (
)} {options.resize && (
)}
); };