Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Contact Picker Dialog Block for React

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.

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

Choose who a message goes to without leaving it, with this recipient picker for React with Base UI. It opens from a message being written in Postbag, an email client: the page's header holds an outline Choose recipients Button, and the compose window itself, a title bar, a To line, a subject and a body, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog is a split. At the start are a search Input that narrows fourteen contacts by name and address, four recent contacts as toggle chips, and the whole address book in alphabetical groups with each letter pinned as you scroll, every row a checkbox with initials, a name and an address. At the end a "To (3)" panel lists the chosen people as chips you can remove, with a Clear button. Add 3 recipients, the only Shine Button, counts as you choose and puts the chips on the drawn To line. For preview the dialog is drawn open in place when the page loads; the Choose recipients button opens the real Dialog, with the same choice. For mail, sharing and message tools, and anywhere a person is picked from a book.

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 compose window: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Choose recipients 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 PickerFields component and share the block's state, so what you chose in the copy is there 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 do I choose and remove people?

Each contact is a native checkbox inside a label, so Space toggles the focused row and pressing anywhere on it works too. The four recent chips toggle the same people, and are pressed when they are chosen. The To panel lists the chosen people in the order you picked them, each with a Remove button named for the person, and Clear takes them all off. After a removal focus moves to the next Remove button, or to the search when none is left. Add recipients with nobody chosen says so under the lists and puts focus in the search.

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

All of it. The fourteen contacts and the four recent ones are typed constants, and Add recipients only puts the chosen people on the drawn To line and says in a polite message that nothing was sent. Cancel and Escape put the choice back to what the message already has. In your app load the book from your API, keep the choice in picked, and on add write the addresses into your message's To field.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus starts in the search and stays inside until it closes, and Escape, Cancel and the close button return focus to Choose recipients. 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, Cancel and its close button close it and put focus on the button.

How does it look on a phone?

The copy shown on load docks to the foot of the page as a bottom sheet, with Add recipients pinned under the body. The To panel becomes a single row of chips under the list that scrolls sideways, so the list keeps its height. The real dialog keeps the Dialog's own phone layout: a sheet stuck to the bottom of the screen.

  • 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

    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.

  • 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

    A mail client in a fixed-height window: mailboxes and labels whose counts follow the mail you file, a searchable message list beside the open message, and Compose for a local draft.

  • Pro

    A mail navbar for an email app with a search field that turns from:, to:, has: and is: operators into removable chips and counts the matches.

  • Pro

    Address Autocomplete Dialog

    Pickers and search

    A meal-kit delivery page with its address dialog shown open: typing filters eight addresses of an invented town into an inline list you can arrow through, a choice fills four editable fields, and Enter it manually offers the same four, empty.