diff --git a/src/elements/SwpEventElement.ts b/src/elements/SwpEventElement.ts
index 60e7b5d..6f79e60 100644
--- a/src/elements/SwpEventElement.ts
+++ b/src/elements/SwpEventElement.ts
@@ -2,166 +2,243 @@ import { CalendarEvent } from '../types/CalendarTypes';
import { calendarConfig } from '../core/CalendarConfig';
import { TimeFormatter } from '../utils/TimeFormatter';
import { PositionUtils } from '../utils/PositionUtils';
-import { EventLayout } from '../utils/AllDayLayoutEngine';
import { DateService } from '../utils/DateService';
/**
- * Abstract base class for event DOM elements
+ * Base class for event elements
*/
-export abstract class BaseEventElement {
- protected element: HTMLElement;
- protected event: CalendarEvent;
+abstract class BaseSwpEventElement extends HTMLElement {
protected dateService: DateService;
- protected constructor(event: CalendarEvent) {
- this.event = event;
+ constructor() {
+ super();
const timezone = calendarConfig.getTimezone?.();
this.dateService = new DateService(timezone);
- this.element = this.createElement();
- this.setDataAttributes();
}
- /**
- * Create the underlying DOM element
- */
- protected abstract createElement(): HTMLElement;
+ // ============================================
+ // Common Getters/Setters
+ // ============================================
- /**
- * Set standard data attributes on the element
- */
- protected setDataAttributes(): void {
- this.element.dataset.eventId = this.event.id;
- this.element.dataset.title = this.event.title;
- this.element.dataset.start = this.dateService.toUTC(this.event.start);
- this.element.dataset.end = this.dateService.toUTC(this.event.end);
- this.element.dataset.type = this.event.type;
- this.element.dataset.duration = this.event.metadata?.duration?.toString() || '60';
+ get eventId(): string {
+ return this.dataset.eventId || '';
+ }
+ set eventId(value: string) {
+ this.dataset.eventId = value;
}
- /**
- * Get the DOM element
- */
- public getElement(): HTMLElement {
- return this.element;
+ get start(): Date {
+ return new Date(this.dataset.start || '');
+ }
+ set start(value: Date) {
+ this.dataset.start = this.dateService.toUTC(value);
}
- /**
- * Format time for display using TimeFormatter
- */
- protected formatTime(date: Date): string {
- return TimeFormatter.formatTime(date);
+ get end(): Date {
+ return new Date(this.dataset.end || '');
+ }
+ set end(value: Date) {
+ this.dataset.end = this.dateService.toUTC(value);
}
- /**
- * Calculate event position for timed events using PositionUtils
- */
- protected calculateEventPosition(): { top: number; height: number } {
- return PositionUtils.calculateEventPosition(this.event.start, this.event.end);
+ get title(): string {
+ return this.dataset.title || '';
+ }
+ set title(value: string) {
+ this.dataset.title = value;
+ }
+
+ get type(): string {
+ return this.dataset.type || 'work';
+ }
+ set type(value: string) {
+ this.dataset.type = value;
}
}
/**
- * Timed event element (swp-event)
+ * Web Component for timed calendar events (Light DOM)
*/
-export class SwpEventElement extends BaseEventElement {
- private constructor(event: CalendarEvent) {
- super(event);
- this.createInnerStructure();
- this.applyPositioning();
- }
+export class SwpEventElement extends BaseSwpEventElement {
- protected createElement(): HTMLElement {
- return document.createElement('swp-event');
+ /**
+ * Observed attributes - changes trigger attributeChangedCallback
+ */
+ static get observedAttributes() {
+ return ['data-start', 'data-end', 'data-title', 'data-type'];
}
/**
- * Create inner HTML structure
+ * Called when element is added to DOM
*/
- private createInnerStructure(): void {
- const timeRange = TimeFormatter.formatTimeRange(this.event.start, this.event.end);
- const durationMinutes = (this.event.end.getTime() - this.event.start.getTime()) / (1000 * 60);
+ connectedCallback() {
+ if (!this.hasChildNodes()) {
+ this.render();
+ }
+ this.applyPositioning();
+ }
- this.element.innerHTML = `
+ /**
+ * Called when observed attribute changes
+ */
+ attributeChangedCallback(name: string, oldValue: string, newValue: string) {
+ if (oldValue !== newValue && this.isConnected) {
+ this.updateDisplay();
+ }
+ }
+
+ // ============================================
+ // Public Methods
+ // ============================================
+
+ /**
+ * Update event position during drag
+ * @param columnDate - The date of the column
+ * @param snappedY - The Y position in pixels
+ */
+ public updatePosition(columnDate: Date, snappedY: number): void {
+ // 1. Update visual position
+ this.style.top = `${snappedY + 1}px`;
+
+ // 2. Calculate new timestamps
+ const { startMinutes, endMinutes } = this.calculateTimesFromPosition(snappedY);
+
+ // 3. Update data attributes (triggers attributeChangedCallback)
+ const startDate = this.dateService.createDateAtTime(columnDate, startMinutes);
+ let endDate = this.dateService.createDateAtTime(columnDate, endMinutes);
+
+ // Handle cross-midnight events
+ if (endMinutes >= 1440) {
+ const extraDays = Math.floor(endMinutes / 1440);
+ endDate = this.dateService.addDays(endDate, extraDays);
+ }
+
+ this.start = startDate;
+ this.end = endDate;
+ }
+
+ /**
+ * Create a clone for drag operations
+ */
+ public createClone(): SwpEventElement {
+ const clone = this.cloneNode(true) as SwpEventElement;
+
+ // Apply "clone-" prefix to ID
+ clone.dataset.eventId = `clone-${this.eventId}`;
+
+ // Cache original duration
+ const timeEl = this.querySelector('swp-event-time');
+ if (timeEl) {
+ const duration = timeEl.getAttribute('data-duration');
+ if (duration) {
+ clone.dataset.originalDuration = duration;
+ }
+ }
+
+ // Set height from original
+ clone.style.height = this.style.height || `${this.getBoundingClientRect().height}px`;
+
+ return clone;
+ }
+
+ // ============================================
+ // Private Methods
+ // ============================================
+
+ /**
+ * Render inner HTML structure
+ */
+ private render(): void {
+ const start = this.start;
+ const end = this.end;
+ const timeRange = TimeFormatter.formatTimeRange(start, end);
+ const durationMinutes = (end.getTime() - start.getTime()) / (1000 * 60);
+
+ this.innerHTML = `
${timeRange}
- ${this.event.title}
+ ${this.title}
`;
}
/**
- * Apply positioning styles
+ * Update time display when attributes change
+ */
+ private updateDisplay(): void {
+ const timeEl = this.querySelector('swp-event-time');
+ const titleEl = this.querySelector('swp-event-title');
+
+ if (timeEl && this.dataset.start && this.dataset.end) {
+ const start = new Date(this.dataset.start);
+ const end = new Date(this.dataset.end);
+ const timeRange = TimeFormatter.formatTimeRange(start, end);
+ timeEl.textContent = timeRange;
+
+ // Update duration attribute
+ const durationMinutes = (end.getTime() - start.getTime()) / (1000 * 60);
+ timeEl.setAttribute('data-duration', durationMinutes.toString());
+ }
+
+ if (titleEl && this.dataset.title) {
+ titleEl.textContent = this.dataset.title;
+ }
+ }
+
+ /**
+ * Apply initial positioning based on start/end times
*/
private applyPositioning(): void {
- const position = this.calculateEventPosition();
- this.element.style.top = `${position.top + 1}px`;
- this.element.style.height = `${position.height - 3}px`;
- this.element.style.left = '2px';
- this.element.style.right = '2px';
+ const position = PositionUtils.calculateEventPosition(this.start, this.end);
+ this.style.top = `${position.top + 1}px`;
+ this.style.height = `${position.height - 3}px`;
+ this.style.left = '2px';
+ this.style.right = '2px';
}
/**
- * Factory method to create a SwpEventElement from a CalendarEvent
+ * Calculate start/end minutes from Y position
+ */
+ private calculateTimesFromPosition(snappedY: number): { startMinutes: number; endMinutes: number } {
+ const gridSettings = calendarConfig.getGridSettings();
+ const { hourHeight, dayStartHour, snapInterval } = gridSettings;
+
+ // Get original duration
+ const originalDuration = parseInt(
+ this.dataset.originalDuration ||
+ this.dataset.duration ||
+ '60'
+ );
+
+ // Calculate snapped start minutes
+ const minutesFromGridStart = (snappedY / hourHeight) * 60;
+ const actualStartMinutes = (dayStartHour * 60) + minutesFromGridStart;
+ const snappedStartMinutes = Math.round(actualStartMinutes / snapInterval) * snapInterval;
+
+ // Calculate end minutes
+ const endMinutes = snappedStartMinutes + originalDuration;
+
+ return { startMinutes: snappedStartMinutes, endMinutes };
+ }
+
+ // ============================================
+ // Static Factory Methods
+ // ============================================
+
+ /**
+ * Create SwpEventElement from CalendarEvent
*/
public static fromCalendarEvent(event: CalendarEvent): SwpEventElement {
- return new SwpEventElement(event);
- }
+ const element = document.createElement('swp-event') as SwpEventElement;
+ const timezone = calendarConfig.getTimezone?.();
+ const dateService = new DateService(timezone);
- /**
- * Create a clone of this SwpEventElement with "clone-" prefix
- */
- public createClone(): SwpEventElement {
- // Clone the underlying DOM element
- const clonedElement = this.element.cloneNode(true) as HTMLElement;
+ element.dataset.eventId = event.id;
+ element.dataset.title = event.title;
+ element.dataset.start = dateService.toUTC(event.start);
+ element.dataset.end = dateService.toUTC(event.end);
+ element.dataset.type = event.type;
+ element.dataset.duration = event.metadata?.duration?.toString() || '60';
- // Create new SwpEventElement instance from the cloned DOM
- const clonedSwpEvent = SwpEventElement.fromExistingElement(clonedElement);
-
- // Apply "clone-" prefix to ID
- clonedSwpEvent.updateEventId(`clone-${this.event.id}`);
-
- // Cache original duration for drag operations
- const originalDuration = this.getOriginalEventDuration();
- clonedSwpEvent.element.dataset.originalDuration = originalDuration.toString();
-
- // Set height from original element
- clonedSwpEvent.element.style.height = this.element.style.height || `${this.element.getBoundingClientRect().height}px`;
-
- return clonedSwpEvent;
- }
-
- /**
- * Factory method to create SwpEventElement from existing DOM element
- */
- public static fromExistingElement(element: HTMLElement): SwpEventElement {
- // Extract CalendarEvent data from DOM element
- const event = this.extractCalendarEventFromElement(element);
-
- // Create new instance but replace the created element with the existing one
- const swpEvent = new SwpEventElement(event);
- swpEvent.element = element;
-
- return swpEvent;
- }
-
- /**
- * Update the event ID in both the CalendarEvent and DOM element
- */
- private updateEventId(newId: string): void {
- this.event.id = newId;
- this.element.dataset.eventId = newId;
- }
-
- /**
- * Extract original event duration from DOM element
- */
- private getOriginalEventDuration(): number {
- const timeElement = this.element.querySelector('swp-event-time');
- if (timeElement) {
- const duration = timeElement.getAttribute('data-duration');
- if (duration) {
- return parseInt(duration);
- }
- }
- return 60; // Fallback
+ return element;
}
/**
@@ -186,7 +263,6 @@ export class SwpEventElement extends BaseEventElement {
* Factory method to convert an all-day HTML element to a timed SwpEventElement
*/
public static fromAllDayElement(allDayElement: HTMLElement): SwpEventElement {
- // Extract data from all-day element's dataset
const eventId = allDayElement.dataset.eventId || '';
const title = allDayElement.dataset.title || allDayElement.textContent || 'Untitled';
const type = allDayElement.dataset.type || 'work';
@@ -198,11 +274,9 @@ export class SwpEventElement extends BaseEventElement {
throw new Error('All-day element missing start/end dates');
}
- // Parse dates and set reasonable 1-hour duration for timed event
const originalStart = new Date(startStr);
- const duration = durationStr ? parseInt(durationStr) : 60; // Default 1 hour
+ const duration = durationStr ? parseInt(durationStr) : 60;
- // For conversion, use current time or a reasonable default (9 AM)
const now = new Date();
const startDate = new Date(originalStart);
startDate.setHours(now.getHours() || 9, now.getMinutes() || 0, 0, 0);
@@ -210,7 +284,6 @@ export class SwpEventElement extends BaseEventElement {
const endDate = new Date(startDate);
endDate.setMinutes(endDate.getMinutes() + duration);
- // Create CalendarEvent object
const calendarEvent: CalendarEvent = {
id: eventId,
title: title,
@@ -224,48 +297,49 @@ export class SwpEventElement extends BaseEventElement {
}
};
- return new SwpEventElement(calendarEvent);
+ return SwpEventElement.fromCalendarEvent(calendarEvent);
}
}
/**
- * All-day event element (now using unified swp-event tag)
+ * Web Component for all-day calendar events
*/
-export class SwpAllDayEventElement extends BaseEventElement {
+export class SwpAllDayEventElement extends BaseSwpEventElement {
- constructor(event: CalendarEvent) {
- super(event);
- this.setAllDayAttributes();
- this.createInnerStructure();
- // this.applyGridPositioning();
- }
-
- protected createElement(): HTMLElement {
- return document.createElement('swp-event');
- }
-
- /**
- * Set all-day specific attributes
- */
- private setAllDayAttributes(): void {
- this.element.dataset.allday = "true";
- this.element.dataset.start = this.dateService.toUTC(this.event.start);
- this.element.dataset.end = this.dateService.toUTC(this.event.end);
- }
-
- /**
- * Create inner structure (just text content for all-day events)
- */
- private createInnerStructure(): void {
- this.element.textContent = this.event.title;
+ connectedCallback() {
+ if (!this.textContent) {
+ this.textContent = this.dataset.title || 'Untitled';
+ }
}
/**
* Apply CSS grid positioning
*/
- public applyGridPositioning(layout: EventLayout): void {
- const gridArea = `${layout.row} / ${layout.startColumn} / ${layout.row + 1} / ${layout.endColumn + 1}`;
- this.element.style.gridArea = gridArea;
+ public applyGridPositioning(row: number, startColumn: number, endColumn: number): void {
+ const gridArea = `${row} / ${startColumn} / ${row + 1} / ${endColumn + 1}`;
+ this.style.gridArea = gridArea;
}
-}
\ No newline at end of file
+ /**
+ * Create from CalendarEvent
+ */
+ public static fromCalendarEvent(event: CalendarEvent): SwpAllDayEventElement {
+ const element = document.createElement('swp-allday-event') as SwpAllDayEventElement;
+ const timezone = calendarConfig.getTimezone?.();
+ const dateService = new DateService(timezone);
+
+ element.dataset.eventId = event.id;
+ element.dataset.title = event.title;
+ element.dataset.start = dateService.toUTC(event.start);
+ element.dataset.end = dateService.toUTC(event.end);
+ element.dataset.type = event.type;
+ element.dataset.allDay = 'true';
+ element.textContent = event.title;
+
+ return element;
+ }
+}
+
+// Register custom elements
+customElements.define('swp-event', SwpEventElement);
+customElements.define('swp-allday-event', SwpAllDayEventElement);
\ No newline at end of file
diff --git a/src/managers/DragDropManager.ts b/src/managers/DragDropManager.ts
index 002f96c..e91b250 100644
--- a/src/managers/DragDropManager.ts
+++ b/src/managers/DragDropManager.ts
@@ -185,12 +185,9 @@ export class DragDropManager {
// Detect current column
this.currentColumnBounds = ColumnDetectionUtils.getColumnBounds(currentPosition);
- // Create SwpEventElement from existing DOM element and clone it
- const originalSwpEvent = SwpEventElement.fromExistingElement(this.draggedElement);
- const clonedSwpEvent = originalSwpEvent.createClone();
-
- // Get the cloned DOM element
- this.draggedClone = clonedSwpEvent.getElement();
+ // Cast to SwpEventElement and create clone
+ const originalSwpEvent = this.draggedElement as SwpEventElement;
+ this.draggedClone = originalSwpEvent.createClone();
const dragStartPayload: DragStartEventPayload = {
draggedElement: this.draggedElement,
diff --git a/src/renderers/AllDayEventRenderer.ts b/src/renderers/AllDayEventRenderer.ts
index c3b9fe8..2c42d4a 100644
--- a/src/renderers/AllDayEventRenderer.ts
+++ b/src/renderers/AllDayEventRenderer.ts
@@ -76,10 +76,10 @@ export class AllDayEventRenderer {
const container = this.getContainer();
if (!container) return null;
- let dayEvent = new SwpAllDayEventElement(event);
- dayEvent.applyGridPositioning(layout);
+ const dayEvent = SwpAllDayEventElement.fromCalendarEvent(event);
+ dayEvent.applyGridPositioning(layout.row, layout.startColumn, layout.endColumn);
- container.appendChild(dayEvent.getElement());
+ container.appendChild(dayEvent);
}
diff --git a/src/renderers/EventRenderer.ts b/src/renderers/EventRenderer.ts
index c74b0b5..237e961 100644
--- a/src/renderers/EventRenderer.ts
+++ b/src/renderers/EventRenderer.ts
@@ -43,86 +43,6 @@ export class DateEventRenderer implements EventRendererStrategy {
}
- /**
- * Update clone timestamp based on new position
- */
- private updateCloneTimestamp(payload: DragMoveEventPayload): void {
- if (payload.draggedClone.dataset.allDay === "true" || !payload.columnBounds) return;
-
- const gridSettings = calendarConfig.getGridSettings();
- const { hourHeight, dayStartHour, snapInterval } = gridSettings;
-
- if (!payload.draggedClone.dataset.originalDuration) {
- throw new DOMException("missing clone.dataset.originalDuration");
- }
-
- // Calculate snapped start minutes
- const minutesFromGridStart = (payload.snappedY / hourHeight) * 60;
- const snappedStartMinutes = this.calculateSnappedMinutes(
- minutesFromGridStart, dayStartHour, snapInterval
- );
-
- // Calculate end minutes
- const originalDuration = parseInt(payload.draggedClone.dataset.originalDuration);
- const endTotalMinutes = snappedStartMinutes + originalDuration;
-
- // Update UI
- this.updateTimeDisplay(payload.draggedClone, snappedStartMinutes, endTotalMinutes);
-
- // Update data attributes
- this.updateDateTimeAttributes(
- payload.draggedClone,
- new Date(payload.columnBounds.date),
- snappedStartMinutes,
- endTotalMinutes
- );
- }
-
- /**
- * Calculate snapped minutes from grid start
- */
- private calculateSnappedMinutes(minutesFromGridStart: number, dayStartHour: number, snapInterval: number): number {
- const actualStartMinutes = (dayStartHour * 60) + minutesFromGridStart;
- return Math.round(actualStartMinutes / snapInterval) * snapInterval;
- }
-
- /**
- * Update time display in the UI
- */
- private updateTimeDisplay(element: HTMLElement, startMinutes: number, endMinutes: number): void {
- const timeElement = element.querySelector('swp-event-time');
- if (!timeElement) return;
-
- const startTime = this.formatTimeFromMinutes(startMinutes);
- const endTime = this.formatTimeFromMinutes(endMinutes);
- timeElement.textContent = `${startTime} - ${endTime}`;
- }
-
- /**
- * Update data-start and data-end attributes with ISO timestamps
- */
- private updateDateTimeAttributes(element: HTMLElement, columnDate: Date, startMinutes: number, endMinutes: number): void {
- const startDate = this.dateService.createDateAtTime(columnDate, startMinutes);
-
- let endDate = this.dateService.createDateAtTime(columnDate, endMinutes);
-
- // Handle cross-midnight events
- if (endMinutes >= 1440) {
- const extraDays = Math.floor(endMinutes / 1440);
- endDate = this.dateService.addDays(endDate, extraDays);
- }
-
- // Convert to UTC before storing as ISO string
- element.dataset.start = this.dateService.toUTC(startDate);
- element.dataset.end = this.dateService.toUTC(endDate);
- }
-
- /**
- * Format minutes since midnight to time string
- */
- private formatTimeFromMinutes(totalMinutes: number): string {
- return this.dateService.minutesToTime(totalMinutes);
- }
/**
* Handle drag start event
@@ -155,15 +75,12 @@ export class DateEventRenderer implements EventRendererStrategy {
* Handle drag move event
*/
public handleDragMove(payload: DragMoveEventPayload): void {
- if (!this.draggedClone) return;
-
- // Update position - snappedY is already the event top position
- // Add +1px to match the initial positioning offset from SwpEventElement
- this.draggedClone.style.top = (payload.snappedY + 1) + 'px';
-
- // Update timestamp display
- this.updateCloneTimestamp(payload);
+ if (!this.draggedClone || !payload.columnBounds) return;
+ // Delegate to SwpEventElement to update position and timestamps
+ const swpEvent = this.draggedClone as SwpEventElement;
+ const columnDate = new Date(payload.columnBounds.date);
+ swpEvent.updatePosition(columnDate, payload.snappedY);
}
/**
@@ -191,16 +108,9 @@ export class DateEventRenderer implements EventRendererStrategy {
// Recalculate timestamps with new column date
const currentTop = parseFloat(this.draggedClone.style.top) || 0;
- const mockPayload: DragMoveEventPayload = {
- draggedElement: dragColumnChangeEvent.originalElement,
- draggedClone: this.draggedClone,
- mousePosition: dragColumnChangeEvent.mousePosition,
- mouseOffset: { x: 0, y: 0 },
- columnBounds: dragColumnChangeEvent.newColumn,
- snappedY: currentTop
- };
-
- this.updateCloneTimestamp(mockPayload);
+ const swpEvent = this.draggedClone as SwpEventElement;
+ const columnDate = new Date(dragColumnChangeEvent.newColumn.date);
+ swpEvent.updatePosition(columnDate, currentTop);
}
}
@@ -272,8 +182,7 @@ export class DateEventRenderer implements EventRendererStrategy {
}
private renderEvent(event: CalendarEvent): HTMLElement {
- const swpEvent = SwpEventElement.fromCalendarEvent(event);
- return swpEvent.getElement();
+ return SwpEventElement.fromCalendarEvent(event);
}
protected calculateEventPosition(event: CalendarEvent): { top: number; height: number } {
diff --git a/src/renderers/EventRendererManager.ts b/src/renderers/EventRendererManager.ts
index ad35e84..959564b 100644
--- a/src/renderers/EventRendererManager.ts
+++ b/src/renderers/EventRendererManager.ts
@@ -247,8 +247,7 @@ export class EventRenderingService {
// Use SwpEventElement factory to create day event from all-day event
- const dayEventElement = SwpEventElement.fromAllDayElement(allDayClone as HTMLElement);
- const dayElement = dayEventElement.getElement();
+ const dayElement = SwpEventElement.fromAllDayElement(allDayClone as HTMLElement);
// Remove the all-day clone - it's no longer needed since we're converting to day event
allDayClone.remove();
diff --git a/wwwroot/css/calendar-layout-css.css b/wwwroot/css/calendar-layout-css.css
index e6c9fd0..d341193 100644
--- a/wwwroot/css/calendar-layout-css.css
+++ b/wwwroot/css/calendar-layout-css.css
@@ -321,7 +321,7 @@ swp-allday-column {
}
/* All-day events in containers */
-swp-allday-container swp-event {
+swp-allday-container swp-allday-event {
height: 22px !important; /* Fixed height for consistent stacking */
position: relative !important;
width: auto !important;
@@ -353,7 +353,7 @@ swp-allday-container swp-event {
}
/* Overflow indicator styling */
-swp-allday-container swp-event.max-event-indicator {
+swp-allday-container swp-allday-event.max-event-indicator {
background: #e0e0e0 !important;
color: #666 !important;
border: 1px dashed #999 !important;
@@ -364,13 +364,13 @@ swp-allday-container swp-event.max-event-indicator {
justify-content: center;
}
-swp-allday-container swp-event.max-event-indicator:hover {
+swp-allday-container swp-allday-event.max-event-indicator:hover {
background: #d0d0d0 !important;
color: #333 !important;
opacity: 1;
}
-swp-allday-container swp-event.max-event-indicator span {
+swp-allday-container swp-allday-event.max-event-indicator span {
display: block;
width: 100%;
text-align: center;
@@ -378,23 +378,23 @@ swp-allday-container swp-event.max-event-indicator span {
font-weight: normal;
}
-swp-allday-container swp-event.max-event-overflow-show {
+swp-allday-container swp-allday-event.max-event-overflow-show {
opacity: 1;
transition: opacity 0.3s ease-in-out;
}
-swp-allday-container swp-event.max-event-overflow-hide {
+swp-allday-container swp-allday-event.max-event-overflow-hide {
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
/* Hide time element for all-day styled events */
-swp-allday-container swp-event swp-event-time{
+swp-allday-container swp-allday-event swp-event-time{
display: none;
}
/* Adjust title display for all-day styled events */
-swp-allday-container swp-event swp-event-title {
+swp-allday-container swp-allday-event swp-event-title {
display: block;
font-size: 12px;
line-height: 18px;