import React, { useState, useEffect, useMemo } from 'react'; import { useSearch } from '@embedpdf/plugin-search/react'; import { useViewer } from '../../contexts/ViewerContext'; import { SEARCH_CONSTANTS } from './constants/search'; interface SearchLayerProps { pageIndex: number; scale: number; highlightColor?: string; activeHighlightColor?: string; opacity?: number; padding?: number; borderRadius?: number; } interface SearchResultState { results: Array<{ pageIndex: number; rects: Array<{ origin: { x: number; y: number }; size: { width: number; height: number }; }>; }>; activeResultIndex?: number; } export function CustomSearchLayer({ pageIndex, scale, highlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.BACKGROUND, activeHighlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.ACTIVE_BACKGROUND, opacity = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.OPACITY, padding = SEARCH_CONSTANTS.UI.HIGHLIGHT_PADDING, borderRadius = 4 }: SearchLayerProps) { const { provides: searchProvides } = useSearch(); const { scrollActions } = useViewer(); const [searchResultState, setSearchResultState] = useState(null); // Subscribe to search result state changes useEffect(() => { if (!searchProvides) { return; } const unsubscribe = searchProvides.onSearchResultStateChange?.((state: SearchResultState) => { // Auto-scroll to active search result if (state?.results && state.activeResultIndex !== undefined && state.activeResultIndex >= 0) { const activeResult = state.results[state.activeResultIndex]; if (activeResult) { const pageNumber = activeResult.pageIndex + 1; // Convert to 1-based page number scrollActions.scrollToPage(pageNumber); } } setSearchResultState(state); }); return unsubscribe; }, [searchProvides, pageIndex]); // Filter results for current page while preserving original indices const pageResults = useMemo(() => { if (!searchResultState?.results) { return []; } const filtered = searchResultState.results .map((result, originalIndex) => ({ result, originalIndex })) .filter(({ result }) => result.pageIndex === pageIndex); return filtered; }, [searchResultState, pageIndex]); if (!pageResults.length) { return null; } return (
{pageResults.map(({ result, originalIndex }, idx) => (
{result.rects.map((rect, rectIdx) => (
))}
))}
); }