shadcn.io is not affiliated with official shadcn/ui
Search Highlight Text marks every place a query appears in a text, the way find-in-page does, and draws the marks in as the query changes: each one is underlined at once, then filled from the underline up, one after another in reading order. Case and accents are ignored by default, so "resume" finds "Résumé".
Use it under a search field on a docs page, an FAQ, terms and conditions or a long list, where people need to see at a glance where their words are. For the same marks without the motion, use Highlight; to walk through the matches of a regular expression, Regex Text; to draw one phrase of your own copy, Highlight Text. The search is a plain string search, never a regular expression, and the marks are drawn by a CSS keyframe animation the install adds to your stylesheet, with no animation library. With reduced motion the marks are simply there.
Installation
Usage
import {
SearchHighlightText,
} from "@/components/ui/search-highlight-text";<SearchHighlightText query={query} text="Every component ships as source you own." />Demos
Sensitivity
sensitivity is which differences between letters count, as in Intl.Collator: base, the default, ignores case and accents; accent ignores case only; case ignores accents only; variant matches exactly. The marks always hold the text as it's written.
Color
highlightColor takes any CSS colour; theme variables mixed with transparent, such as color-mix(in oklab, var(--info) 30%, transparent), keep the text readable on it, light and dark. Style the marks themselves through data-slot="search-highlight-text-mark" or a [&_mark]: class.
Accessibility
The text stays real text, read once by screen readers, with each match in a <mark>, which some of them announce as highlighted. The number of matches matters most to someone who can't see the marks: onMatchCountChange gives it to you whenever it changes, to show beside the search field in a polite status, as the first demo does ("2 matches"). In forced-colors mode the marks take the system's highlight colours. With reduced motion they're drawn at once.
FAQ
How is it different from Highlight?
Highlight marks the matches of one or several terms, case-sensitive by default, with no motion. Search Highlight Text is made for a search as it's typed: it ignores case and accents, draws each new set of marks in, and tells you how many there are.
Can someone type characters like a dot or a bracket?
Yes. The query is found as plain text, never compiled into a regular expression, so ., *, ( and \ are just themselves and nothing someone types can break it.
How are accents ignored?
Each character is split into its letter and its accents (Unicode's NFD form) and the accents dropped, in the text and in the query alike, so "cafe" finds "Café" and "Café" finds "cafe". The marks still hold the text exactly as written.
How do I show the number of matches?
Pass onMatchCountChange, such as a state setter: it's called with the count whenever it changes. Show it in an element with role="status" so screen readers hear it as the query changes, without moving focus.
What happens with a blank query?
Nothing is marked and the count is 0. A query of spaces counts as blank, and spaces around a query are ignored.
API Reference
SearchHighlightText
<span> data-slot="search-highlight-text"
querystring
What to find in the text; blank marks nothing.
textstring
The text to search.
highlightColor?string
The marks' colour, any CSS colour; keep it light enough for the text to read on it.
- Default
"color-mix(in oklab, var(--warning) 40%, transparent)"
onMatchCountChange?(count: number) → void
Called with the number of matches whenever it changes, to show it or announce it.
- Parameters
count– number- Returns
void
sensitivity?Sensitivity
Which differences between letters count, as in Intl.Collator: base
ignores case and accents (e finds É), accent ignores case only,
case ignores accents only, variant matches exactly.
- Default
"base"
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--search-highlight-text-colorstring
The marks' colour.
Related
- Pro
Regex Text
DecorativeWalk through matches of a pattern
Highlight Text
DecorativeDraw one phrase of your own copy
- Pro
Annotation Text
DecorativeA pen mark around a word
- Pro
Redact Text
DecodeHide words, then show them in turn
- Pro
Magnify Text
InteractiveA lens for fine print
- Pro
Skeleton Text
EntranceResults that arrive in place of bars