Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Merge Accounts Dialog Block for React

A contacts page with its merge dialog shown open: two accounts that look like one person in a table, matching fields marked Same, a radio in each cell where they differ, a Result column that follows your choices, and Merge accounts waiting until every conflict is chosen.

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 someone settle a duplicate one field at a time, with this merge accounts dialog for React with Base UI. It opens from the contacts page of Ravelton, a small-team CRM: the page's header holds an outline Review duplicates Button, and the list, a search bar, a banner counting the possible duplicates, a few contacts and the two that look alike, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog has an Alert saying what a real merge does, then a table: the field, the first account, the second account and the Result. Fields that match say Same and show their value once; the four that differ (name, phone, plan and last seen) have a radio in each account's cell, and the Result column shows your pick as you make it. A line counts the conflicts and says which remain, and Merge accounts, the only Shine Button, waits until every conflict is chosen. Merging writes the Result onto the drawn contact and takes the duplicate off the list. For preview the dialog is drawn open in place when the page loads; the header button opens the real dialog, with the same choices. For CRMs, address books, accounts and any app that finds the same person twice.

FAQ

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

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Review duplicates button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same MergeFields component and share the block's state, so a value chosen in the copy is chosen in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

How does it know which fields differ?

By comparing the two accounts' values in the file: a field whose two values are equal is a Same row, and every other row is a conflict with one radio for each account. Last seen starts on the newer date, as a rule in your app might set it, and says so with a Newer badge; the other three start with nothing chosen, so the count reads 4 conflicts, 1 resolved. The Result column is not a copy of anything: it prints the value for the side you picked, or Choose one.

Why does Merge accounts wait, and what happens when you press it early?

Because a merge with an unanswered question would have to guess. Until every conflict has a pick the button keeps its place on the page with a quiet look, and the line beside the count names what is left ("Still to choose: Name, Phone and Plan"). Pressing it anyway says the same in the status line and moves focus to the first conflict that is still open, so the next step is one key away.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus starts on the first conflict, and Escape, Cancel and the close button return focus to the Review duplicates button. Each radio is a native radio named for its field and its account ("Phone, account B: +1 555 0177"), the arrow keys move between the two accounts of a row, the table has a caption and row headers, and what changes is spoken once in a polite status line (inside the dialog while it is open). The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange.

What stays local, and how do I wire it for real?

Everything. Nothing merges and nothing is deleted: the two accounts are typed in the file, and Merge accounts only changes this block's state and the drawn contact. In your app send the choices to your API, keep one contact and move the other's notes, deals and history onto it, keep the removed contact's id so old links still resolve, and ask for a second confirmation if your merge cannot be undone.

How does it look on a phone?

The copy shown on load docks to the foot of the page as a bottom sheet with its buttons pinned and the content scrolling above them. The table becomes one card per field from the same markup: the field's name, the two accounts' values as two full-width choices, and the Result under them; fields that match shrink to one line. The real dialog keeps the Dialog's own phone layout, a sheet stuck to the bottom of the screen.

  • Pro

    Sync Conflict Error

    Files and data

    A panel for two people who changed the same document: ruled rows for the fields that differ, each with Yours and Theirs as native radio cells, a Keep all toggle, a merged result that rebuilds as you choose, and the unchanged fields in a collapsible.

  • Pro

    A file-sync folder with its conflict alert shown open: the two copies of a spreadsheet side by side with when, who and how big, four ways to settle it, an Apply to all option, and the next conflict loading after each answer.

  • Pro

    Contact Card Dialog

    Share and invite

    A team directory with a contact card shown open that pages through six people: initials avatar, role, email, phone, desk and the time where they are, copy buttons, real mailto and tel links, and a Save contact button that downloads a vCard.

  • Pro

    When a provider's email is not yours: a table of what each provider returned, a choice under each mismatch to add it as a second email or keep it separate, and a count of sign-ins that would make a new account.

  • Pro

    Contact Picker Dialog

    Pickers and search

    A compose window with its recipient picker shown open: a search over fourteen contacts, four recent ones as toggles, an alphabetical list with pinned letters, a To panel of removable chips, and an Add recipients button that fills the message's To line.

  • Pro

    Create Poll Dialog

    Notes and editing

    A neighbourhood forum thread with a poll builder shown open: a question, two to six options, one answer or several, how long it stays open, and a live preview of the poll as voters will see it.