useDocumentSearch
Searches the document text: set a query, step through the matches, and let the SDK highlight them on the pages and scroll to the active one. Re-renders the component as the search progresses.
const {
criteria,
matches,
activeMatchIndex,
status,
setSearchCriteria,
goToNextMatch,
goToPreviousMatch,
goToMatch,
} = useDocumentSearch()Every hook call shares the same search, so a search bar and a results list in different components stay in sync. Each loaded document starts with an empty query and every option off.
State
| Field | Type | Meaning |
|---|---|---|
criteria | SearchCriteria | The query and the options, as last set. |
matches | readonly SearchMatch[] | The matches in document order: page by page, and within a page paragraph by paragraph. |
activeMatchIndex | number | The index of the active match in matches, or -1 when no match is active. |
status | SearchStatus | How far the search has gone through the document. |
SearchCriteria fields:
| Field | Type | Meaning |
|---|---|---|
query | string | The text to find. '' means no search. |
isCaseSensitive | boolean | Match the letter case of the query exactly. |
isWholeWord | boolean | Skip occurrences that continue a word on either side. Letters, digits, combining marks, and _ make up words. |
SearchMatch fields:
| Field | Type | Meaning |
|---|---|---|
id | string | Identifies the match for React keys and goToMatch (session-scoped). |
pageId | string | The page the match is on, as the page hooks such as useScrollToPage accept it. |
paragraphId | string | The paragraph the match is in, as the block hooks such as useScrollToBlock accept it. |
text | string | The matched text as it appears in the document. |
SearchStatus is one of:
| Status | Meaning |
|---|---|
'idle' | There is no query. |
'searching' | The criteria changed and the search hasn't gone through the whole document yet. matches grows meanwhile. |
'complete' | The whole document is searched. The matches keep following the edits. A page whose text fails to load is skipped. |
Actions
setSearchCriteria(criteria)starts a search for new criteria. To change one field, spreadcriteriainto the call:setSearchCriteria({ ...criteria, isWholeWord: true }).- A changed query is searched once typing pauses, so
statusis'searching'with no matches for a moment. - Changing an option without changing the query searches at once.
- The first match found becomes active and is scrolled to.
- A query of
''drops the matches and every highlight. - Criteria equal to the current ones change nothing.
- A changed query is searched once typing pauses, so
goToNextMatch()andgoToPreviousMatch()activate the next or previous match and scroll to it, wrapping around at the ends. They do nothing when there are no matches.goToMatch(matchId)activates the match with the given id and scrolls to it. It does nothing when no match has that id, such as one read before an edit removed it.
Behavior
- The matches follow the document: edits, undo, and redo update them, and the active match stays on its occurrence.
matchesis a new array only when the list changes, and an unchanged match keeps its object, so a results list can memoize its rows by match.- A match id comes from its paragraph and its position among the paragraph's matches. An edit that adds or removes an earlier match in the same paragraph moves the id to a neighboring match.
Highlight styling
The SDK paints the matches inside the page text. Style them through the searchMatch key of the theme prop on PdfProviders, or through the CSS variables on the viewport:
| CSS variable | Default | What it colors |
|---|---|---|
--search-match-background | rgba(255, 213, 0, 0.4) | Every match. |
--search-match-active-background | rgba(255, 149, 0, 0.55) | The active match. |
- A
classNames.searchMatchclass styles the active match apart with a[data-active]selector. - A
styles.searchMatchentry is written to the element as is: give lengths units ('4px', not4). - Use paint properties only, such as
backgroundandcolor: a padding, margin, or border moves the document text.
Example
import { useDocumentSearch } from '@sdk-pdf/react'
function SearchBar() {
const {
criteria,
matches,
activeMatchIndex,
status,
setSearchCriteria,
goToNextMatch,
goToPreviousMatch,
} = useDocumentSearch()
return (
<div>
<input
value={criteria.query}
placeholder="Search"
onChange={(event) =>
setSearchCriteria({ ...criteria, query: event.target.value })
}
onKeyDown={(event) => {
if (event.key === 'Enter')
(event.shiftKey ? goToPreviousMatch : goToNextMatch)()
}}
/>
<label>
<input
type="checkbox"
checked={criteria.isCaseSensitive}
onChange={(event) =>
setSearchCriteria({ ...criteria, isCaseSensitive: event.target.checked })
}
/>
Match case
</label>
<span>
{matches.length > 0
? `${activeMatchIndex + 1} of ${matches.length}`
: status === 'complete'
? 'No results'
: ''}
</span>
</div>
)
}See also useScrollToBlock and Theming and customization.