shadcn.io is not affiliated with official shadcn/ui
Add Comment Dialog Block for Svelte
A design-review tool's wireframe with its comment dialog shown open: a 500-character field where typing @ opens an inline people list, up to three attached files, and the thread so far beside it.
Installation
Overview
Let a reviewer say exactly what they see and who should look, with this comment dialog for Svelte with Ark UI. It opens from a Checkout redesign under review on Inkpin, a design-review tool: the header holds an outline Add comment Button, and the page, a wireframe with a header, a hero and three cards, numbered pins and a side panel of comments, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog is titled "Comment on Header" for pin 3. A Textarea stops at 500 characters and counts what is left; typing an @ opens a Listbox of five people under the field, and the arrow keys and Enter insert "@Maren". Under it a File Upload takes up to three files and lists their names and sizes. At the end the thread so far shows the two earlier comments with initials, pin and age; on a phone it folds into a Collapsible under the composer. Comment, the only Shine Button, adds yours to the thread and pin 3 to the wireframe. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog.
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 Add comment 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 CommentFields component and share the block's state, so a comment 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 does the @ list work?
It reads the letters between an @ and the caret. As soon as there is a match the list takes the place of the attachments below the field, in the same box, so nothing moves. Keep typing to narrow it, press Down to move into the list and Enter to insert, or press Enter in the field to take the first match. The mention is written as "@" and the first name, a space follows, and the caret lands after it. The list is inline, never a popup, so it works inside the dialog on all four bases. Deleting the @ or moving the caret away closes it; Escape closes the dialog as usual.
What happens to the attached files?
Nothing leaves the device. The file chooser or a drop gives the block the files' names and sizes, which it lists with a remove button each; the bytes are never read. Up to three files of 5 MB each are accepted and anything else is refused with a line saying so. In your app upload from post, show progress on each file, and revoke anything you created with an object URL.
What does Comment do, and what stays local?
Here it adds your comment to the thread in this page's state with a pin 3 badge and the text in the drawn side panel, lights pin 3 on the wireframe, and says in a polite status message that nothing was posted. An empty comment is refused under the field, "Write a comment first.", with focus back in it. In your app post the text, the mentioned people's ids, the pin's position and the files from post, and notify the people who were mentioned.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus starts in the comment field and stays inside until it closes, and Escape, Cancel and the close button all return focus to Add comment. The trigger is the Add comment button wrapped in DialogTrigger with asChild, 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 Add comment. The people list is a listbox named "People to mention".
How does it look on a phone?
The copy shown on load docks to the foot of the page as a bottom sheet with Cancel and Comment pinned at the bottom. The composer comes first and the thread is a closed "Thread so far (2)" disclosure under it, so the field is within the first screen. The real dialog keeps the Dialog's own phone layout: a sheet stuck to the bottom of the screen.