63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import React from 'react';
|
|
import type { SearchResult } from '../lib/gatewayService';
|
|
|
|
interface SearchOverlayLayerProps {
|
|
pageIndex: number;
|
|
width: number;
|
|
height: number;
|
|
zoom: number;
|
|
searchQuery: string;
|
|
searchResults?: SearchResult[];
|
|
searchCurrentMatch?: number;
|
|
}
|
|
|
|
export const SearchOverlayLayer: React.FC<SearchOverlayLayerProps> = ({
|
|
pageIndex,
|
|
width,
|
|
height,
|
|
zoom,
|
|
searchQuery,
|
|
searchResults = [],
|
|
searchCurrentMatch = 0,
|
|
}) => {
|
|
if (!searchQuery || searchResults.length === 0) return null;
|
|
|
|
// Filter results for this specific page and keep track of global index
|
|
const pageMatches = searchResults
|
|
.map((result, globalIndex) => ({ ...result, globalIndex }))
|
|
.filter((result) => result.pageIndex === pageIndex);
|
|
|
|
if (pageMatches.length === 0) return null;
|
|
|
|
return (
|
|
<div
|
|
className="absolute top-0 left-0 pointer-events-none z-20"
|
|
style={{ width: `${width}px`, height: `${height}px` }}
|
|
>
|
|
{pageMatches.map((match) => (
|
|
<React.Fragment key={match.globalIndex}>
|
|
{match.rects.map((rect, rectIdx) => {
|
|
const isActive = match.globalIndex === searchCurrentMatch;
|
|
return (
|
|
<div
|
|
key={rectIdx}
|
|
className={`absolute rounded-sm border ${
|
|
isActive
|
|
? 'bg-orange-500/50 border-orange-600/80 shadow-[0_0_8px_rgba(249,115,22,0.6)] z-30'
|
|
: 'bg-yellow-400/40 border-yellow-500/60'
|
|
}`}
|
|
style={{
|
|
left: `${rect.x * zoom}px`,
|
|
top: `${rect.y * zoom}px`,
|
|
width: `${rect.w * zoom}px`,
|
|
height: `${rect.h * zoom}px`,
|
|
}}
|
|
/>
|
|
);
|
|
})}
|
|
</React.Fragment>
|
|
))}
|
|
</div>
|
|
);
|
|
};
|