Refactors all-day event drag and drop handling for improved accuracy and performance. Introduces a shared `ColumnDetectionUtils` for consistent column detection. Simplifies all-day conversion during drag, placing events in row 1 and calculating the column from the target date. Implements differential updates during drag end, updating only changed events for smoother transitions.
254 lines
5.4 KiB
CSS
254 lines
5.4 KiB
CSS
/* styles/components/events.css */
|
|
|
|
/* Event base styles */
|
|
swp-day-columns swp-event {
|
|
position: absolute;
|
|
border-radius: 3px;
|
|
overflow: hidden;
|
|
cursor: pointer;
|
|
transition: box-shadow 150ms ease, transform 150ms ease;
|
|
z-index: 10;
|
|
left: 2px;
|
|
right: 2px;
|
|
color: var(--color-text);
|
|
font-size: 12px;
|
|
padding: 2px 4px;
|
|
|
|
/* Event types */
|
|
&[data-type="meeting"] {
|
|
background: var(--color-event-meeting);
|
|
border-left: 4px solid var(--color-event-meeting-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&[data-type="meal"] {
|
|
background: var(--color-event-meal);
|
|
border-left: 4px solid var(--color-event-meal-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&[data-type="work"] {
|
|
background: var(--color-event-work);
|
|
border-left: 4px solid var(--color-event-work-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&[data-type="milestone"] {
|
|
background: var(--color-event-milestone);
|
|
border-left: 4px solid var(--color-event-milestone-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&[data-type="personal"] {
|
|
background: var(--color-event-personal);
|
|
border-left: 4px solid var(--color-event-personal-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
&[data-type="deadline"] {
|
|
background: var(--color-event-milestone);
|
|
border-left: 4px solid var(--color-event-milestone-border);
|
|
color: var(--color-text);
|
|
}
|
|
|
|
/* Dragging state */
|
|
&.dragging {
|
|
position: absolute;
|
|
z-index: 999999;
|
|
pointer-events: none;
|
|
opacity: 0.8;
|
|
left: 2px;
|
|
right: 2px;
|
|
margin-left: 0px;
|
|
width: auto;
|
|
}
|
|
|
|
}
|
|
|
|
swp-day-columns swp-event:hover {
|
|
box-shadow: var(--shadow-md);
|
|
transform: translateX(2px);
|
|
z-index: 20;
|
|
}
|
|
|
|
swp-day-columns swp-event-time {
|
|
display: block;
|
|
font-size: 0.875rem;
|
|
font-weight: 500;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
swp-day-columns swp-event-title {
|
|
display: block;
|
|
font-size: 0.875rem;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
/* External resize handles */
|
|
swp-resize-handle {
|
|
position: absolute;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 24px;
|
|
height: 4px;
|
|
opacity: 0;
|
|
transition: opacity var(--transition-fast);
|
|
cursor: ns-resize;
|
|
z-index: 30;
|
|
background: var(--color-primary);
|
|
border-radius: 3px;
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
|
|
/* Subtle grip pattern */
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 50%;
|
|
top: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: 12px;
|
|
height: 1px;
|
|
background: rgba(255, 255, 255, 0.6);
|
|
border-radius: 0.5px;
|
|
box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.3);
|
|
}
|
|
}
|
|
|
|
/* Top resize handle - positioned OUTSIDE event */
|
|
swp-resize-handle[data-position="top"] {
|
|
top: -6px;
|
|
}
|
|
|
|
/* Bottom resize handle - positioned OUTSIDE event */
|
|
swp-resize-handle[data-position="bottom"] {
|
|
bottom: -6px;
|
|
}
|
|
|
|
/* Resize handles controlled by JavaScript - no general hover */
|
|
swp-handle-hitarea {
|
|
position: absolute;
|
|
left: -8px;
|
|
right: -8px;
|
|
top: -6px;
|
|
bottom: -6px;
|
|
cursor: ns-resize;
|
|
}
|
|
|
|
swp-handle-hitarea[data-position="top"] {
|
|
top: 4px;
|
|
}
|
|
|
|
swp-handle-hitarea[data-position="bottom"] {
|
|
bottom: 4px;
|
|
}
|
|
|
|
/* Multi-day events */
|
|
swp-multi-day-event {
|
|
position: relative;
|
|
height: 28px;
|
|
margin: 2px 4px;
|
|
padding: 0 8px;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 0.875rem;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all var(--transition-fast);
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
|
|
/* Event type colors */
|
|
&[data-type="milestone"] {
|
|
background: var(--color-event-milestone);
|
|
color: var(--color-event-milestone-border);
|
|
}
|
|
|
|
/* Continuation indicators */
|
|
&[data-continues-before="true"] {
|
|
border-top-left-radius: 0;
|
|
border-bottom-left-radius: 0;
|
|
margin-left: 0;
|
|
padding-left: 20px;
|
|
|
|
&::before {
|
|
content: '◀';
|
|
position: absolute;
|
|
left: 4px;
|
|
opacity: 0.6;
|
|
font-size: 0.75rem;
|
|
}
|
|
}
|
|
|
|
&[data-continues-after="true"] {
|
|
border-top-right-radius: 0;
|
|
border-bottom-right-radius: 0;
|
|
margin-right: 0;
|
|
padding-right: 20px;
|
|
|
|
&::after {
|
|
content: '▶';
|
|
position: absolute;
|
|
right: 4px;
|
|
opacity: 0.6;
|
|
font-size: 0.75rem;
|
|
}
|
|
}
|
|
|
|
&:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-sm);
|
|
}
|
|
}
|
|
|
|
/* Event creation preview */
|
|
swp-event-preview {
|
|
position: absolute;
|
|
left: 8px;
|
|
right: 8px;
|
|
background: rgba(33, 150, 243, 0.1);
|
|
border: 2px dashed var(--color-primary);
|
|
border-radius: 4px;
|
|
pointer-events: none;
|
|
|
|
/* Position via CSS variables */
|
|
top: calc(var(--preview-start) * var(--minute-height));
|
|
height: calc(var(--preview-duration) * var(--minute-height));
|
|
}
|
|
|
|
/* Event filtering styles */
|
|
/* When filter is active, all events are dimmed by default */
|
|
swp-events-layer[data-filter-active="true"] swp-event {
|
|
opacity: 0.2;
|
|
transition: opacity 200ms ease;
|
|
}
|
|
|
|
/* Events that match the filter stay normal */
|
|
swp-events-layer[data-filter-active="true"] swp-event[data-matches="true"] {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Event overlap styling */
|
|
/* Event group container for column sharing */
|
|
swp-event-group {
|
|
position: absolute;
|
|
display: flex;
|
|
gap: 1px;
|
|
width: calc(100% - 4px);
|
|
left: 2px;
|
|
z-index: 10;
|
|
}
|
|
|
|
swp-event-group swp-event {
|
|
flex: 1;
|
|
position: relative;
|
|
left: 0;
|
|
right: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
/* All-day event transition for smooth repositioning */
|
|
swp-allday-container swp-event.transitioning {
|
|
transition: grid-area 200ms ease-out, grid-row 200ms ease-out, grid-column 200ms ease-out;
|
|
}
|