feat: make event over flow show on hover

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-07-03 20:23:50 -04:00
parent 1ffbfc0c3d
commit bdac31e8e7
+50 -54
View File
@@ -181,35 +181,19 @@ function getSingleDayEvents(date: Date): CalendarInstance[] {
} }
// "+N more" popover listing all of a day's events // "+N more" popover listing all of a day's events
const morePopover = ref<{ open: boolean; target: HTMLElement | null; date: Date | null }>({ function morePopoverLabel(date: Date): string {
open: false, return date.toLocaleDateString('en-US', {
target: null,
date: null,
});
function showMorePopover(event: MouseEvent, date: Date) {
morePopover.value = {
open: true,
target: event.currentTarget as HTMLElement,
date,
};
}
const morePopoverInstances = computed<CalendarInstance[]>(() => {
return morePopover.value.date ? instancesStore.instancesForDay(morePopover.value.date) : [];
});
const morePopoverLabel = computed(() => {
return morePopover.value.date?.toLocaleDateString('en-US', {
weekday: 'short', weekday: 'short',
month: 'short', month: 'short',
day: 'numeric', day: 'numeric',
}) ?? ''; });
}); }
function onPopoverEventClick(instance: CalendarInstance) { function formatStartTime(instance: CalendarInstance): string {
morePopover.value.open = false; return new Date(instance.startMs).toLocaleTimeString('en-US', {
emit('event-click', instance.entity); hour: 'numeric',
minute: '2-digit',
});
} }
function isToday(date: Date): boolean { function isToday(date: Date): boolean {
@@ -280,9 +264,42 @@ function getEventColor(instance: CalendarInstance): string {
<div <div
v-if="cell.hiddenCount > 0" v-if="cell.hiddenCount > 0"
class="more-events" class="more-events"
@click.stop="showMorePopover($event, cell.date)" @click.stop
> >
+{{ cell.hiddenCount }} more +{{ cell.hiddenCount }} more
<v-menu
activator="parent"
open-on-hover
open-on-click
:open-delay="150"
:close-delay="200"
location="bottom"
:offset="4"
>
<v-card min-width="220" max-width="320">
<div class="more-popover-header">{{ morePopoverLabel(cell.date) }}</div>
<v-list density="compact">
<v-list-item
v-for="instance in instancesStore.instancesForDay(cell.date)"
:key="instance.key"
@click="$emit('event-click', instance.entity)"
>
<template #prepend>
<span
class="more-popover-dot"
:style="{ backgroundColor: getEventColor(instance) }"
></span>
</template>
<v-list-item-title>
<span v-if="!instance.timeless" class="more-popover-time">
{{ formatStartTime(instance) }}
</span>
{{ instance.label || 'Untitled' }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-card>
</v-menu>
</div> </div>
</div> </div>
</div> </div>
@@ -315,34 +332,6 @@ function getEventColor(instance: CalendarInstance): string {
</div> </div>
</div> </div>
</div> </div>
<!-- "+N more" popover: all events for the selected day -->
<v-menu
v-if="morePopover.target"
v-model="morePopover.open"
:activator="morePopover.target"
location="bottom"
:offset="4"
>
<v-card min-width="220" max-width="320">
<div class="more-popover-header">{{ morePopoverLabel }}</div>
<v-list density="compact">
<v-list-item
v-for="instance in morePopoverInstances"
:key="instance.key"
@click="onPopoverEventClick(instance)"
>
<template #prepend>
<span
class="more-popover-dot"
:style="{ backgroundColor: getEventColor(instance) }"
></span>
</template>
<v-list-item-title>{{ instance.label || 'Untitled' }}</v-list-item-title>
</v-list-item>
</v-list>
</v-card>
</v-menu>
</div> </div>
</template> </template>
@@ -576,6 +565,13 @@ function getEventColor(instance: CalendarInstance): string {
font-weight: 600; font-weight: 600;
} }
.more-popover-time {
font-size: 11px;
opacity: 0.7;
font-variant-numeric: tabular-nums;
margin-right: 4px;
}
.more-popover-dot { .more-popover-dot {
width: 10px; width: 10px;
height: 10px; height: 10px;