Fix lint issues and improve EventViewer component

- Fix biome lint formatting issues
- Add onActiveIndexChange callback for controlled state
- Simplify WebsocketEventDetail to compute message internally
- Fix exhaustive deps warning in handleRowClick

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-01-09 15:49:11 -08:00
parent 928099c6fd
commit 904d0063d6
4 changed files with 69 additions and 54 deletions

View File

@@ -1,4 +1,4 @@
import { type Virtualizer, useVirtualizer } from '@tanstack/react-virtual';
import { useVirtualizer, type Virtualizer } from '@tanstack/react-virtual';
import type { ReactElement, ReactNode, UIEvent } from 'react';
import { useCallback, useLayoutEffect, useRef, useState } from 'react';
import { IconButton } from './IconButton';

View File

@@ -48,6 +48,9 @@ interface EventViewerProps<T> {
/** Message to show when no events */
emptyMessage?: string;
/** Callback when active index changes (for controlled state in parent) */
onActiveIndexChange?: (index: number | null) => void;
}
export function EventViewer<T>({
@@ -63,8 +66,22 @@ export function EventViewer<T>({
isLoading = false,
loadingMessage = 'Loading events...',
emptyMessage = 'No events recorded',
onActiveIndexChange,
}: EventViewerProps<T>) {
const [activeIndex, setActiveIndex] = useState<number | null>(null);
const [activeIndex, setActiveIndexInternal] = useState<number | null>(null);
// Wrap setActiveIndex to notify parent
const setActiveIndex = useCallback(
(indexOrUpdater: number | null | ((prev: number | null) => number | null)) => {
setActiveIndexInternal((prev) => {
const newIndex =
typeof indexOrUpdater === 'function' ? indexOrUpdater(prev) : indexOrUpdater;
onActiveIndexChange?.(newIndex);
return newIndex;
});
},
[onActiveIndexChange],
);
const containerRef = useRef<HTMLDivElement>(null);
const virtualizerRef = useRef<Virtualizer<HTMLDivElement, Element> | null>(null);
@@ -101,7 +118,7 @@ export function EventViewer<T>({
(index: number) => {
setActiveIndex((prev) => (prev === index ? null : index));
},
[],
[setActiveIndex],
);
if (isLoading) {
@@ -154,7 +171,7 @@ export function EventViewer<T>({
<Separator />
</div>
<div className="mx-2 overflow-y-auto">
{renderDetail({ event: activeEvent, index: activeIndex! })}
{renderDetail({ event: activeEvent, index: activeIndex ?? 0 })}
</div>
</div>
)