Improves drag and drop functionality

Enhances drag and drop behavior by introducing free positioning during auto-scroll and snapping to grid intervals.

- Introduces a `calculateFreePosition` method to allow events to follow the mouse exactly during auto-scroll.
- Modifies the drag move event to emit the snapped position during normal drag behavior.
- Updates event rendering to use grid settings for snap intervals.
- Updates grid styles to configure CSS variables dynamically.
This commit is contained in:
Janus Knudsen 2025-09-03 20:48:23 +02:00
parent b4d758b6d9
commit 7a1c776bc1
4 changed files with 50 additions and 25 deletions

View file

@ -159,25 +159,26 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
const gridSettings = calendarConfig.getGridSettings();
const hourHeight = gridSettings.hourHeight;
const dayStartHour = gridSettings.dayStartHour;
const snapInterval = 15; // TODO: Get from config
const snapInterval = gridSettings.snapInterval;
// Calculate total minutes from top
const totalMinutesFromTop = (snappedY / hourHeight) * 60;
const startTotalMinutes = Math.max(
dayStartHour * 60,
Math.round((dayStartHour * 60 + totalMinutesFromTop) / snapInterval) * snapInterval
);
// Calculate minutes from grid start (not from midnight)
const minutesFromGridStart = (snappedY / hourHeight) * 60;
// Add dayStartHour offset to get actual time
const actualStartMinutes = (dayStartHour * 60) + minutesFromGridStart;
// Snap to interval
const snappedStartMinutes = Math.round(actualStartMinutes / snapInterval) * snapInterval;
// Use cached original duration (no recalculation)
const cachedDuration = parseInt(clone.dataset.originalDuration || '60');
const endTotalMinutes = startTotalMinutes + cachedDuration;
const endTotalMinutes = snappedStartMinutes + cachedDuration;
// Update display
const timeElement = clone.querySelector('swp-event-time');
if (timeElement) {
const newTimeText = `${this.formatTime(startTotalMinutes)} - ${this.formatTime(endTotalMinutes)}`;
const newTimeText = `${this.formatTime(snappedStartMinutes)} - ${this.formatTime(endTotalMinutes)}`;
timeElement.textContent = newTimeText;
}
}
@ -619,19 +620,20 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
const dayStartHour = gridSettings.dayStartHour;
const hourHeight = gridSettings.hourHeight;
// Calculate minutes from visible day start
// Calculate minutes from midnight
const startMinutes = startDate.getHours() * 60 + startDate.getMinutes();
const endMinutes = endDate.getHours() * 60 + endDate.getMinutes();
const dayStartMinutes = dayStartHour * 60;
// Calculate top position (subtract day start to align with time axis)
// Calculate top position relative to visible grid start
// If dayStartHour=6 and event starts at 09:00 (540 min), then:
// top = ((540 - 360) / 60) * hourHeight = 3 * hourHeight (3 hours from grid start)
const top = ((startMinutes - dayStartMinutes) / 60) * hourHeight;
// Calculate height
// Calculate height based on event duration
const durationMinutes = endMinutes - startMinutes;
const height = (durationMinutes / 60) * hourHeight;
return { top, height };
}