Implement highlight effect on the day navigated to.
This commit is contained in:
@@ -17,16 +17,7 @@ const formattedDate = computed(() => {
|
||||
<div
|
||||
class="cell"
|
||||
:style="props.dragging ? 'touch-action:none;' : 'touch-action:pan-y;'"
|
||||
:class="[
|
||||
props.day.monthClass,
|
||||
{
|
||||
today: props.day.isToday,
|
||||
weekend: props.day.isWeekend,
|
||||
firstday: props.day.isFirstDay,
|
||||
selected: props.day.isSelected,
|
||||
holiday: props.day.isHoliday,
|
||||
},
|
||||
]"
|
||||
:class="[props.day.monthClass, { today: props.day.isToday, weekend: props.day.isWeekend, firstday: props.day.isFirstDay, selected: props.day.isSelected, holiday: props.day.isHoliday }]"
|
||||
:data-date="props.day.date"
|
||||
>
|
||||
<span class="compact-date">{{ formattedDate }}</span>
|
||||
@@ -43,10 +34,8 @@ const formattedDate = computed(() => {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
display: grid;
|
||||
/* Updated grid for centered day number */
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr auto;
|
||||
/* Named grid areas */
|
||||
grid-template-areas:
|
||||
'day-number'
|
||||
'holiday-info';
|
||||
@@ -89,6 +78,26 @@ const formattedDate = computed(() => {
|
||||
z-index: 15;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Search highlight animation */
|
||||
.cell.search-highlight-flash::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: calc(100% + .2rem);
|
||||
height: calc(100% + .2rem);
|
||||
border-radius: 1rem;
|
||||
background: transparent;
|
||||
border: 0.3em solid var(--strong);
|
||||
z-index: 16;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cell.search-highlight-flash::after { animation: search-highlight-flash 1.5s ease-out forwards; }
|
||||
|
||||
@keyframes search-highlight-flash {0%{opacity:0;transform:translate(-50%,-50%) scale(.8);border-width:.1em}15%{opacity:1;transform:translate(-50%,-50%) scale(1.05);border-width:.4em}30%{opacity:1;transform:translate(-50%,-50%) scale(1);border-width:.3em}100%{opacity:0;transform:translate(-50%,-50%) scale(1);border-width:.3em}}
|
||||
.cell.selected h1.day-number {
|
||||
opacity: 0.3;
|
||||
filter: brightness(1.2);
|
||||
|
||||
@@ -197,11 +197,24 @@ function measureFromProbe() {
|
||||
const {
|
||||
getWeekIndex,
|
||||
getFirstDayForVirtualWeek,
|
||||
goToToday,
|
||||
handleHeaderYearChange,
|
||||
scrollToWeekCentered,
|
||||
} = vwm
|
||||
|
||||
function showDay(input) {
|
||||
const dateStr = input instanceof Date ? toLocalString(input, DEFAULT_TZ) : String(input)
|
||||
const weekIndex = getWeekIndex(fromLocalString(dateStr, DEFAULT_TZ))
|
||||
scrollToWeekCentered(weekIndex, 'nav', true)
|
||||
const diff = Math.abs(weekIndex - centerVisibleWeek.value)
|
||||
const delay = Math.min(800, diff * 40)
|
||||
setTimeout(() => {
|
||||
const el = document.querySelector(`[data-date="${dateStr}"]`)
|
||||
if (!el) return
|
||||
el.classList.add('search-highlight-flash')
|
||||
setTimeout(() => el.classList.remove('search-highlight-flash'), 1500)
|
||||
}, delay)
|
||||
}
|
||||
|
||||
// Reference date for search: center of the current viewport (virtual week at vertical midpoint)
|
||||
const centerVisibleWeek = computed(() => {
|
||||
const midRow = (scrollTop.value + viewportHeight.value / 2) / rowHeight.value
|
||||
@@ -457,26 +470,15 @@ const handleEventClick = (payload) => {
|
||||
openEditEventDialog(payload)
|
||||
}
|
||||
|
||||
function scrollToEventStart(startDate, smooth = true) {
|
||||
try {
|
||||
const dateObj = fromLocalString(startDate, DEFAULT_TZ)
|
||||
const weekIndex = getWeekIndex(dateObj)
|
||||
scrollToWeekCentered(weekIndex, 'search-jump', smooth)
|
||||
} catch {
|
||||
/* noop */
|
||||
function handleHeaderSearchPreview(r) { if (r) showDay(r.startDate) }
|
||||
function handleHeaderSearchActivate(r) {
|
||||
if (!r) return
|
||||
showDay(r.startDate)
|
||||
if (!r._goto && !r._holiday) {
|
||||
const ev = calendarStore.getEventById(r.id)
|
||||
if (ev) openEditEventDialog({ id: ev.id, event: ev })
|
||||
}
|
||||
}
|
||||
function handleHeaderSearchPreview(result) {
|
||||
if (!result) return
|
||||
scrollToEventStart(result.startDate, true)
|
||||
}
|
||||
function handleHeaderSearchActivate(result) {
|
||||
if (!result) return
|
||||
scrollToEventStart(result.startDate, true)
|
||||
// Open edit dialog for the event
|
||||
const ev = calendarStore.getEventById(result.id)
|
||||
if (ev) openEditEventDialog({ id: ev.id, event: ev })
|
||||
}
|
||||
|
||||
// Heuristic: rotate month label (180deg) only for predominantly Latin text.
|
||||
// We explicitly avoid locale detection; rely solely on characters present.
|
||||
@@ -543,7 +545,7 @@ window.addEventListener('resize', () => {
|
||||
<div class="wrap">
|
||||
<HeaderControls
|
||||
:reference-date="centerVisibleDateStr"
|
||||
@go-to-today="goToToday"
|
||||
@go-to-today="() => showDay(calendarStore.today)"
|
||||
@search-preview="handleHeaderSearchPreview"
|
||||
@search-activate="handleHeaderSearchActivate"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user