fix: auto-scroll to top for EventFeed and LogViewer
All checks were successful
Build & Publish / publish (push) Successful in 52s

Newest entries appear at the top in descending sort, so auto-scroll
should snap to top instead of bottom.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-26 15:45:30 +01:00
parent 2a020c1e15
commit d101d883a9
2 changed files with 13 additions and 13 deletions

View File

@@ -81,25 +81,25 @@ export function EventFeed({ events, maxItems = 200, className }: EventFeedProps)
.filter((e) => activeFilters.size === 0 || activeFilters.has(e.severity))
.filter((e) => !searchLower || getSearchableText(e).toLowerCase().includes(searchLower))
// Auto-scroll to bottom
const scrollToBottom = useCallback(() => {
// Auto-scroll to top (newest entries are at top in desc sort)
const scrollToTop = useCallback(() => {
const el = scrollRef.current
if (el) {
el.scrollTop = el.scrollHeight
el.scrollTop = 0
}
}, [])
useEffect(() => {
if (!isPaused) {
scrollToBottom()
scrollToTop()
}
}, [events, isPaused, scrollToBottom])
}, [events, isPaused, scrollToTop])
function handleScroll() {
const el = scrollRef.current
if (!el) return
const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 8
setIsPaused(!atBottom)
const atTop = el.scrollTop < 8
setIsPaused(!atTop)
}
function toggleFilter(severity: SeverityFilter) {
@@ -196,10 +196,10 @@ export function EventFeed({ events, maxItems = 200, className }: EventFeedProps)
className={styles.resumeBtn}
onClick={() => {
setIsPaused(false)
scrollToBottom()
scrollToTop()
}}
>
Resume auto-scroll
&uarr; Scroll to latest
</button>
)}
</div>

View File

@@ -35,18 +35,18 @@ function formatTime(iso: string): string {
export function LogViewer({ entries, maxHeight = 400, className }: LogViewerProps) {
const scrollRef = useRef<HTMLDivElement>(null)
const isAtBottomRef = useRef(true)
const isAtTopRef = useRef(true)
const handleScroll = useCallback(() => {
const el = scrollRef.current
if (!el) return
isAtBottomRef.current = el.scrollHeight - el.scrollTop - el.clientHeight < 20
isAtTopRef.current = el.scrollTop < 20
}, [])
useEffect(() => {
const el = scrollRef.current
if (el && isAtBottomRef.current) {
el.scrollTop = el.scrollHeight
if (el && isAtTopRef.current) {
el.scrollTop = 0
}
}, [entries])