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

View File

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