Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Contact Card Dialog Block for React

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.

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

Show who someone is and let people reach them, with this contact card for React with Base UI. It opens from the Directory of Namefold, a small-team directory: the page's header holds an outline View contact card Button, and the directory itself, six drawn tiles, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog shows a large initials avatar, the name and the role, then the person's email, phone, desk and the time where they are, with a Copy Button on the email and the phone. Three actions are real: Email is a mailto link and the only Shine Button, Call is a tel link, and Save contact downloads a vCard file of the typed details. Previous and Next, and the arrow keys, move to the neighbouring person without closing, with "3 of 6" between them. The last person looked at is outlined on the drawn directory and a saved one carries a bookmark. For preview the card is drawn open in place when the page loads; the header button opens the real Dialog, at the same person. For directories, rosters and any app where a person has a page.

FAQ

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

So you can see it without a click. On load the card 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 View contact card 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 ContactCard component and share the block's state, so the person you paged to in the copy is the one 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.

What does Save contact download?

A real .vcf file, a vCard 3.0, built from the typed details: the name in both forms, the organisation, the role, the work email, the work phone and a note with the desk and the city. Lines end with CRLF, as the format asks, and the file name is the person's id. Opening it in an address book adds a contact there. Pressing the button also marks the person as saved on the drawn directory and says so in a polite message. In your app build the card from your own record in vcardOf.

How do Previous, Next and the arrow keys work?

They step round the six people, so the first card follows the last. Focus stays on the button you pressed, a polite message says the new name and "2 of 6", and the card keeps its size whoever it shows. The arrow keys move while focus is anywhere inside the card, except in a field, and follow the reading direction: in a right-to-left page the left arrow is next.

Where does the time come from?

From a fixed instant, AS_OF, shown in each person's time zone with Intl.DateTimeFormat, so "10:40 in Toronto" is the same for everyone whenever they look. It is not your clock. In your app read the current time in clockOf and refresh it on a timer, or say "now" and let the browser format it.

What stays local in the demo, and how do I wire it up?

All but the file and the links. The six people are typed constants and nothing is stored or sent; the copy buttons use the clipboard, which needs a page served over HTTPS, and say so if it refuses. In your app load the person from your API, keep the index in the list you are paging, and keep the links and the vCard.

Is it accessible from the keyboard?

Yes. The real dialog is named by the person's name and described by their role, focus starts inside the card and stays inside until it closes, and Escape and the close button return focus to View contact card. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it and its close button close it and put focus on the button.

  • 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

    Invite Members Dialog

    Share and invite

    A household calendar's Members page with its invite dialog shown open: one email field that knows the household's domain, so an outside address joins as a guest, the people who already have access, and a Send invite button that adds a pending row.

  • Pro

    Sortable Directory Team

    Lists and directories

    A document-signing company's ten people in a table whose cells share their hairlines, sorted by name, department or tenure from the header, with a tenure bar and a live sort announcement.

  • Pro

    Contact Support Dialog

    Feedback and reports

    A shipments table with a support dialog shown open: a ticket form with a category, a priority and attached file names, and beside it up to three help articles picked by the category and the subject's words, each opening in place.

  • Pro

    Profile Drawer Team

    Lists and directories

    Eight people of a design agency as rows that each open one side drawer with a quote, a bio and three career figures, with Previous and Next buttons that step through the team without closing the drawer.

  • Pro

    Invite Team Dialog

    Share and invite

    A crew page with its bulk invite dialog shown open: a pasted list becomes one chip per address with bad ones flagged, one role for the batch, a seat meter that refuses a batch that does not fit, and a Pending tab with Resend, Revoke and Undo.