shadcn.io is not affiliated with official shadcn/ui
Feature Request Dialog Block for React
A public roadmap with a request dialog shown open: the title finds similar requests as you type, each with a vote toggle and its count, voting instead closes the dialog, and a new request lands on top of the board's Considering lane.
Installation
Overview
Stop the fifth copy of the same request, with this dialog for React with Base UI. It opens from the public roadmap of Roadlit: the header holds an outline Request a feature Button, and the board itself, three lanes of cards, Considering, Planned and Shipped, 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 the title Input, a category Native Select, how much it matters in a Radio Group and optional details in a Textarea. At the end are the eight requests that already exist, narrowing as you type to the ones that share a word with the title, the shared word marked with Search Highlight Text, each with a Toggle that votes and shows its count. "Mine is different" folds the list away, and on a phone the list is a disclosure under the title. Voting closes the dialog with "Voted for Offline mode"; Submit request, the only Shine Button, puts the new request on top of Considering. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same fields and the same list.
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 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 Request a feature 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 RequestFields component and share the block's state, so what you typed 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 are similar requests found?
By words, not by a search service. similarTo folds the title (case and accents ignored), keeps the words of three letters or more, and lists the requests whose titles contain any of them, the most matching words first and then the most votes; with nothing typed it lists the most voted. Each row marks the longest word it shares, so the marks and the list can't disagree. A polite count is said 600 ms after you stop typing, never on every key. In your app call your own search and keep the same row.
What happens when I vote instead of asking?
Pressing Vote adds one to that request's count, closes the dialog and says "Voted for Offline mode. Nothing was posted in this demo." The drawn board raises the card's count to match. Reopening shows the toggle pressed and "Voted"; pressing it again takes the vote back and keeps the dialog open. Votes are kept in the block's state, one per request, and are not sent anywhere.
What does Mine is different do?
It folds the list away and says "Hidden. Yours goes in as a new request", with a button that shows it again; the box keeps its height, so the fields beside it don't move. The category and the impact are always asked, and a title of fewer than six characters is refused with a message under the field and focus back in it. In your app the same button is a good place to record that a person saw the duplicates and went on anyway.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus starts in the title and stays inside until it closes, and Escape, Cancel and the close button return focus to Request a feature. Each Vote toggle is named with the request it is for, such as "Vote (23) for Offline mode". 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.
What stays local in the demo, and how do I wire it up?
All of it. The eight requests, their votes and the board are typed constants, and nothing is posted: Submit request adds a card to the drawn Considering lane and says so in a polite message. In your app post the title, category, impact and details from submit, add the card from the response, and ask your server to link the new request to the one a person says it duplicates.
Related
- Pro
Feedback Form Dialog
Drawers and popoversA documentation page with a feedback card docked to its end and shown open: a kind, a message of up to 400 characters with a count, the page it is about, and an optional email that turns on when you let the team reply.
- Pro
Contact Support Dialog
Feedback and reportsA 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
Feedback Rating Dialog
Feedback and reportsA help desk's ended chat with a one-tap satisfaction dialog shown open: five drawn faces from very bad to great that record the score at once, then an optional comment with a question that fits the score.
- Pro
Feature Request Board Changelog
Roadmap and customersAn idea board in a split: a Suggest a feature form beside status tabs with counts and a list of ideas with once-only upvote toggles and comment counts; a submitted idea joins the list locally.
- Pro
App Rating Dialog
Drawers and popoversA water tracker's Today screen with its rating drawer shown open over a drawn phone: five stars with a word each, then a branch, where four or five stars offers the store and one to three asks what could be better, with topics and a note.
- Pro
Mood Check Dialog
Feedback and reportsA mood journal's home with a check-in dialog shown open: five faces from Rough to Great, tags for what is behind the mood, an optional note of 200 characters, and a week strip that fills in today's cell.