shadcn.io is not affiliated with official shadcn/ui
Email Compose Command Menu Block for React
A webmail app's command menu shown open over the Inbox: start a new email, reply or forward the open message in a To, Subject and message form inside the menu, or jump to a folder, and Ctrl or Command Enter sends into the Sent count.
Installation
Overview
Write an email without leaving the keyboard with this email compose command menu for React with Base UI. It opens from the Inbox in Mailrook, a webmail app, whose header holds an outline field with its ⌘ K cap, and the mail app is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The menu is the catalog Command: New email, Reply and Forward come first, then the five folders with their counts. Choosing New email, Reply or Forward turns the menu into a compose form in the same shell, with To, Subject and a message, Reply and Forward already filled in from the open message. Ctrl or ⌘ Enter, or the Send button, checks the address and the subject, then adds the message to the drawn Sent folder: its count goes up, the menu closes and the status line says it was added to Sent in this demo. Choosing a folder goes there and closes the menu. For preview the menu is drawn open in place when the page loads; the field, or Ctrl or ⌘ K while focus is in the block, opens the real command dialog with the same step, draft and query. For webmail, support inboxes and any app where writing is the main action.
FAQ
Why is the menu already open, and what do I keep?
So you can see it without a click. On load the menu is the Command drawn inline over a picture of the Inbox, in a plain shell that is not modal, so nothing is trapped, hidden or focused and the page around the preview keeps working. The header's field opens the real command dialog, modal, with its focus trap, Escape and focus return, and the inline copy stays closed until a reload. Both show the same Palette and share the block's state, so a draft you started in the copy is the one the dialog opens with. In your app keep the dialog and drop the copy: the "in-place" state, the scrim with its shell and the Escape and blur effects.
How does the compose step work?
It replaces the list inside the same shell, so the menu keeps its size and nothing around it moves. New email starts empty; Reply fills To with the sender and Subject with "Re:" and the original subject; Forward fills Subject with "Fwd:" and quotes the original below the cursor. Enter in a field does nothing, so a stray key never sends; Ctrl or ⌘ Enter and the Send button do. Back, or Escape, returns to the list and keeps the draft until you start another.
What does it check before it sends?
Every recipient, split on commas or semicolons, must look like an address (text, an at sign, a domain with a dot), and the subject can't be empty. The problem is written in a line of its own under the message, which keeps its height, and the field it belongs to is marked invalid. A message with a body but no subject is refused rather than sent without a title.
What happens when it sends?
Nothing is delivered. The draft is added to the drawn Sent folder, whose count goes up by one, the folder list behind the menu shows Sent as the current folder, the menu closes and the status line reads "Added to Sent in this demo" with the recipient and the new count. Focus returns to the header's field.
What stays local, and how do I wire it?
All of it. The folders, their counts and the open message are typed data and the draft is state in the block. In your app load FOLDERS and the open message from your mail store, post the draft from send to your API, and only then raise the Sent count and close the menu.
Is it accessible from the keyboard?
Yes. Type to search the actions and folders, the arrow keys move through them, Enter chooses, and Escape steps back from the form, then closes the menu with focus on the field. Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. In the form, Tab moves To, Subject, message, Send. The rows are options of a cmdk listbox; the block turns off its own fuzzy filter and lists the rows itself.
Related
- Pro
Reply Templates Command Menu
Edit and insertA help desk's reply library as a command menu shown open over a ticket: choosing a reply with slots turns the menu into a short form, a textarea previews the filled reply, and Enter inserts it.
- Pro
A notes app's command menu shown open as its panel: type a sentence with #tags and Enter saves it to Recent, tag chips filter the list, and a pin button or Alt P moves a note to Pinned.
- Pro
A team chat's command menu shown open as a dock at the bottom end of a channel: search people and channels with unread counts, see the highlighted one's last three messages, and reply from a field under the list.
- Pro
A product page's command menu shown open under its Feedback button: choose Bug, Idea or Praise, write it with a severity for bugs, and add it to a Recent feedback list with an Open, Planned or Shipped word.
- Pro
Quick Edit Command Menu
Edit and insertA support inbox's quick edit as a command menu shown open under a ticket's header: pick a field, edit it in the right control, see Before and After, and Enter saves into the record card.
- 1234Pro
Account Switcher Command Menu
SwitchersAn agency billing portal's account switcher as a command menu shown open under the account chip: four accounts with initials, role and plan, a tick on the current one, the keys 1 to 4 to switch straight to an account, and the chip and status line that follow the choice.