Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Text

Pro

Redact Text for React

Text with words under black bars that come off one after another, like a declassified file. For React with Base UI, when a line should keep a secret for a moment, then tell it.

Framework

Redact Text covers chosen words with bars, like a declassified file, then takes the bars off one after another, each one wiping away in the reading direction to show the word underneath. By default they come off a moment after the text scrolls into view; they can also come off while the pointer is over the text, or when you say so, from a button.

Use it for a teaser, a launch announcement, a privacy page, or a before and after where the hidden words are the point. For a panel that wipes across a whole line, use Mask Reveal Text; for text that decodes itself, Decrypted Text. The words keep their place under the bars, so nothing moves when they come off: each bar is a clip-path CSS transition, delayed by its place among the bars, with no animation library. With reduced motion the bars simply go.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { RedactText } from "@/components/ui/redact-text";
<RedactText
  text="The secret project employs classified operatives."
  words={["secret", "classified"]}
/>

Demos

Hover

trigger="hover" takes the bars off while the pointer is over the text, and puts them back when it leaves. words takes phrases as well as words: each is one bar.

Preview width

Button

revealed takes the bars off and puts them back when you say, here from a button with aria-pressed; while it's set, the trigger is ignored. barColor is the bars' colour, any CSS colour or theme variable, and stagger the time between one bar and the next.

Preview width

Accessibility

Screen readers never hear a hidden word before it's revealed. They read the sentence from a visually hidden copy that says label, "redacted" by default, in place of each hidden word, and the words themselves once the bars are off; the visible text is hidden from them. When you drive revealed yourself, that copy is a polite live region, so pressing your button reads the revealed sentence out; when the text reveals itself, in view or on the page, it changes quietly. While covered, the words can't be selected either.

Hover is a peek for the pointer alone: a keyboard or a touch screen can't hover, and screen readers keep hearing "redacted". For words everyone should be able to reveal, use a button, as in the demo.

FAQ

How are the words matched?

Whole, and as written: secret covers "secret" but not "Secret" or "secretary". A phrase, such as three time zones, is one bar, and the longest match wins where two overlap. Punctuation around a word stays uncovered.

Can it hide something private?

No. It's a presentation effect: the hidden words are in the page, under the bars, and anyone can read them in its source. To keep something private, don't send it to the page until it's revealed.

How do I reveal it with a click?

Hold revealed in your own state and toggle it from a button, with aria-pressed saying whether the words show, as in the Button demo. Screen readers hear the revealed sentence when it's pressed.

Can the bars come back?

Yes: set revealed back to false and they wipe back on in the same order. With trigger="hover" they come back each time the pointer leaves.

What colour are the bars?

The text's own colour by default, so they're black on a light page and white on a dark one. barColor takes any CSS colour; in forced-colours mode they use the system's text colour.

What does it show without JavaScript?

With trigger="view" or "mount", the words, since nothing would take the bars off. Hover is CSS alone and works as usual.

What happens with reduced motion?

The bars go at once, all together, when they would have wiped away.

API Reference

RedactText

<span> data-slot="redact-text"

PropType
textstring

The text.

wordsstring[]

The words or phrases under bars, matched whole and as written.

barColor?string

The bars' colour, any CSS colour; the text's own colour when unset.

delay?number

The wait before the bars come off, once the trigger has fired, in milliseconds.

Default
600
duration?number

How long one bar takes to come off, in milliseconds. @default 550.

label?string

What screen readers hear in place of each hidden word, until it's revealed.

Default
"redacted"
revealed?boolean

Whether the words are revealed, to drive it yourself (from a button); the trigger is ignored while it's set.

stagger?number

The time between one bar and the next, in milliseconds. @default 200.

trigger?"view" | "mount" | "hover"

What takes the bars off: the text scrolling into view, the page showing it, or the pointer over it (they come back when it leaves).

Type
"view" | "mount" | "hover"
Default
"view"
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.

AttributeType
data-state?string

"revealed" when shown is true, otherwise "redacted".

CSS variableType
--redact-text-bar-colorstring

The bars' colour (currentColor).

--redact-text-durationstring

One bar's wipe (550ms).

--redact-text-indexstring
--redact-text-offstring
--redact-text-staggerstring

The time between one bar and the next (200ms).

All 97 text effects