Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Feedback Command Menu Block for React

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.

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

Collect feedback from wherever the reader is with this feedback command menu for React with Base UI. It opens from the product page in Feedloft, a feedback board, whose header holds an outline field with its ⌘ K cap, and the page is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, its Feedback button at the end of the bar and the menu hanging below it. The menu is the catalog Command in two steps. The first lists Bug, Idea and Praise, and the board's Recent feedback, each item with its kind, an Open, Planned or Shipped word and its votes; choosing a recent item adds your vote, once. The second is a form in the same shell: a bug asks for its severity (Low, Medium or High) with a ToggleGroup, then a message of at least ten characters with a count. Ctrl or ⌘ Enter, or Send, adds it to the top of Recent feedback as Open. 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, message and query. For product pages, docs and any app that wants feedback in two keystrokes.

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 under a picture of the page's Feedback button, 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 message written 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.

What are the two steps?

The list is step one: three kinds to send and the recent items, searchable. Choosing a kind opens step two in the same shell, so the menu keeps its size. The form has a band with Back, a severity slot, the message and a footer with Send. The severity slot keeps its height for every kind: a bug shows the switch, an idea or praise shows a sentence saying it takes none, so the message never jumps.

What does it check, and what does a send do?

A message needs at least ten characters. A shorter one is refused in a line of its own under the field, which says how many you have, and the field is marked invalid. A valid one is added to the top of Recent feedback with its first line as the title, the status Open and one vote, which is yours; the menu goes back to the list and the status line says it was added and that nothing was sent.

How do the votes work?

Choosing a recent item adds one vote and marks the row "you voted"; choosing it again says you already did, so a row can't be inflated. Your own new item starts at one vote for the same reason. The status words are typed data: Open, Planned or Shipped.

What stays local, and how do I wire it?

All of it. The board and the votes are state in the block and the status line says nothing is sent. In your app load START from your feedback API, post from send and pick, and take the status words from your tracker.

Is it accessible from the keyboard?

Yes. Type to search, the arrow keys move through the rows, Enter chooses, and Escape steps back from the form, then closes the menu with focus on the field. In the form Enter writes a new line and Ctrl or ⌘ Enter sends. Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows are options of a cmdk listbox; the block turns off its own fuzzy filter and lists the rows itself.

  • Pro

    A messaging app's help centre as a command menu shown open beside an article pane: articles and video tutorials filter as you type, the pane shows the highlighted one's first paragraph, three headings and related reading, and a contact support row is never filtered out.

  • Pro

    A to-do app's command menu shown open over the Today list: type a sentence to add a task with !1 to !3 setting its priority, tick tasks with Enter or Space, and filter Active, Done or All.

  • Pro

    A release-notes tool's changelog as a command menu shown open under a What's new bell: a select says which version you are on, the list shows what came after it with fixed dates, chips filter by New, Improved or Fixed, and the count line says how many changes break something.

  • Pro

    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.

  • 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

    An 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.