Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Quick Chat Command Menu Block for Ark UI

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.

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

Answer a message without leaving the page with this quick chat command menu for React with Ark UI. It opens from a channel in Murmurfield, team messaging, whose header holds an outline field with its ⌘ K cap, and the channel is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, the menu docked at its bottom end. The menu is the catalog Command over the conversations, people first and then channels, each with an initials avatar and its unread count. The highlighted conversation shows its last three messages in a strip under the list (two on a phone) and a reply field under the strip: Enter in the list opens the conversation, marks it read and moves focus to the reply field, and Enter there appends the reply to the strip. 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 conversations, replies and query. For team chat, support desks and any app where a short answer should not cost a page load.

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 channel, 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 reply sent in the copy is in the strip in the dialog. 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 strip follow the list?

It shows the conversation of the highlighted row, or the first row while nothing is highlighted, so it is never empty. The strip has a fixed height and shows the last three messages at the bottom, so moving the highlight changes the words and never the size. On a phone it keeps two. If the search matches nothing the strip says there is no conversation and the reply field is disabled.

What do Enter in the list and in the field do?

Enter on a conversation opens it: its unread count goes to zero, the total in the foot and in the drawn channel's side list drops by that much, and focus moves to the reply field, named for that conversation. Enter in the field appends your reply, marked "You" and "now", to the strip and clears the field; an empty reply says to write one first. Replies are capped at 200 characters.

How are unread counts shown?

In words, "5 new", beside the name, with a hidden ", unread" for screen readers, and never as a colour. The foot shows the total unread while nothing is typed and the matches while you type. Avatars are initials hidden from assistive technology, so an option reads as the name.

What stays local, and how do I wire it?

All of it. The conversations, their messages and the unread counts are typed data and state in the block, and nothing is sent. In your app load START from your messaging API, send the reply from send, and clear unread from the server's read receipt.

Is it accessible from the keyboard?

Yes. Type to narrow the conversations, the arrow keys move through them, Enter opens one, Tab reaches the reply field and Send, and Escape closes the menu with focus on the field. Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows are options of a combobox and the first is highlighted when it opens.