Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Search Replace Dialog Block for Vue

A document editor's find bar shown open over real text: every match marked with an underline, the current one ringed and scrolled into view, a count like 3 of 12, case and whole-word toggles, Replace and Replace all.

Framework
UI library

Preview

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.

Overview

Let people find and fix words in a document without leaving it, with this find bar for Vue with Ark UI. It opens from the Launch notes page of Wordwarren, a document editor: the page's header holds an outline Find and replace Button, and the page itself, ten lines of real text with a drawn tool rail and breadcrumb, sits in a hairline frame with a plus mark on each corner and no scrim, because the bar isn't modal. The bar is a Popover docked at the end of the frame with a Find Input and its count, "3 of 12", Previous and Next buttons, a Replace input with a Replace button, two Toggles, Match case and Whole word, and the only Shine Button, "Replace all (12)". Every match in the text is a real mark with an underline, the current one with a heavier underline and a ring, so colour is never the only sign, and the page scrolls to it. Replace swaps the current match, Replace all swaps every one, and "No matches" is said in words. Enter goes to the next match and Shift Enter to the previous one. For preview the bar is drawn open in place when the page loads; the header button opens the real Popover, with the same fields and the same text. For editors, notes, wikis and any long text a person has to correct.

FAQ

Why is the bar already open, and what do I keep?

So you can see it without a click. On load the bar is a copy drawn in place at the end of the frame: a native dialog element with no scrim, so nothing is trapped or focused and the text beside it keeps working. The Find and replace button opens the real bar as a non-modal Popover that hangs from the button (Escape closes it and focus goes back to the button), and the copy stays closed until a reload. Both show the same FindBody component and share the block's state. In your app keep the Popover, or dock a panel of your own to the editor, and drop the copy: the "in-place" state and the dialog element beside the text.

How does the matching work?

It is a plain text search over each line, never a regular expression, so any character you type is just itself. Match case compares letters exactly, and Whole word only counts a match that has no letter, digit or underscore next to it, so "launch" skips "relaunch" and "launched". Matches never overlap, they are counted in reading order, and the count in the field and the one on Replace all always agree. A regular-expression mode is left out on purpose: it would need its own handling of invalid patterns.

What do Replace and Replace all change?

Replace swaps the current match and moves to the next one after it, so a replacement that contains the search text is not replaced again. Replace all swaps every match in one go and says how many in a polite message. Both rewrite the page's text in this tab only, and the count updates at once; when nothing matches, the buttons stay in the page but turn quiet and say "No matches to replace" when pressed.

Why underline and a ring instead of a highlight colour?

A pale tint alone is lost on some screens and for some eyes. Each match has a real mark element with an underline and a light fill, and the current match adds a heavier underline and a ring, so it is found by shape and weight. The count is text in the field and a polite message after a short pause when you type, and at once when you press Next or Previous.

Does it save anything, and how do I wire it up?

No. The ten lines are a typed constant held in state, and the replacements live in this tab. In your app run matchesOf over your editor's text model instead, mark the ranges it returns, and apply Replace and Replace all as one edit so Undo takes them back together.

Is it accessible from the keyboard?

Yes. The bar is named Find and replace, focus starts in the Find field, Enter and Shift Enter move through the matches, and Escape closes it and returns focus to the header button; the page can be scrolled with the keyboard while the bar is open. The trigger is the button wrapped in PopoverTrigger with asChild, and the popover is controlled with open and onOpenChange and is not modal. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the header button.