Skip to content

Commit 6d32a8f

Browse files
Kjubikstronkclaude
andcommitted
Show every date at a place, and stop scrolling re-rendering the app
Two dates at one venue drew two markers at identical coordinates — one exactly on top of the other. The one underneath was invisible and impossible to click, so a place you'd been to twice looked like you'd been once. Dates now share a pin when they share a place: the pin wears a count and the card lists all of them, soonest first. Verified with two dates at one venue: seven placed dates draw six pins, and the card shows both. The no-key fallback map had the identical bug, so both now use one grouping function. Scrolling stuttered on phones because cards and calendar cells set state on mouseenter — and touchscreens synthesise mouse events, so dragging a finger past a card re-rendered the whole app, all 42 calendar cells included, mid-scroll. Hover handlers are now only attached on a real pointer, where hover-linking actually means something. DateCard is memoised so an unrelated change doesn't rebuild every card, and the hover lift is behind a hover media query. Also aliased the maps library's Map import: it shadows the global Map constructor, which silently broke `new Map()` in that file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 7d3bf21 commit 6d32a8f

7 files changed

Lines changed: 538 additions & 97 deletions

File tree

‎src/components/Calendar.tsx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,9 @@ export default function Calendar({
253253
onKeyDown={(e) => onKeyDown(e, day)}
254254
onFocus={() => setFocusKey(k)}
255255
onClick={() => onSelect(k)}
256-
onMouseEnter={() => onHoverDay?.(k)}
257-
onMouseLeave={() => onHoverDay?.(null)}
256+
{...(onHoverDay
257+
? { onMouseEnter: () => onHoverDay(k), onMouseLeave: () => onHoverDay(null) }
258+
: {})}
258259
aria-selected={isSelected}
259260
aria-label={`${format(day, 'EEEE d MMMM')}${
260261
entries.length ? `, ${entries.length} planned` : ''
@@ -271,7 +272,7 @@ export default function Calendar({
271272
: outside
272273
? ''
273274
: 'bg-[var(--color-card)]',
274-
!outside && 'hover:-translate-y-0.5',
275+
!outside && '[@media(hover:hover)]:hover:-translate-y-0.5',
275276
]
276277
.filter(Boolean)
277278
.join(' ')}

‎src/components/DateCard.tsx‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react'
1+
import { memo, useState } from 'react'
22
import { format, parseISO } from 'date-fns'
33
import type { DateIdea } from '../types'
44
import PixelHeart from './PixelHeart'
@@ -19,7 +19,7 @@ type Props = {
1919

2020
type Mode = 'idle' | 'calling-off' | 'deleting'
2121

22-
export default function DateCard({
22+
function DateCard({
2323
item,
2424
onUpdate,
2525
onDelete,
@@ -52,8 +52,9 @@ export default function DateCard({
5252
]
5353
.filter(Boolean)
5454
.join(' ')}
55-
onMouseEnter={() => onHover?.(item.id)}
56-
onMouseLeave={() => onHover?.(null)}
55+
{...(onHover
56+
? { onMouseEnter: () => onHover(item.id), onMouseLeave: () => onHover(null) }
57+
: {})}
5758
>
5859
{/* The whole header is the "take me there" target — bigger than any
5960
icon and the obvious thing to hit. */}
@@ -271,3 +272,9 @@ export default function DateCard({
271272
</li>
272273
)
273274
}
275+
276+
/**
277+
* Memoised: the agenda re-renders whenever anything in the app changes, and
278+
* without this every card rebuilt each time — including on scroll.
279+
*/
280+
export default memo(DateCard)

0 commit comments

Comments
 (0)