shadcn.io is not affiliated with official shadcn/ui
Quick Note Dialog Block for React
A sticky-note wall with its dialog shown open: a title, a note of up to 280 characters, an Idea, To-do, Reference or Later label, a reminder day on a calendar and a pin switch, and a new card that lands first on the wall.
Installation
Overview
Capture a thought before it goes, with this note dialog for React with Base UI. It opens from the Wall of Pinwren, a sticky-note wall: the page's header holds an outline New note Button, and the wall, five cards of different heights, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog asks for a title and a note of up to 280 characters in a Textarea, a label from a Toggle Group of four (Idea, To-do, Reference, Later, each a glyph and a word), a reminder day and a Switch that pins the note to the top. The day is picked on an inline Calendar that takes the place of the note's fields while it is open, so the dialog never changes height, and days before the date the demo treats as today are closed. Save note is the only Shine Button: the new card lands first on the wall, pinned cards before the others, with its label, its reminder day and the title and the text you typed as real text. 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 wall: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The New note 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 NoteFields 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 does the note land on the wall?
Save note asks for a title first, naming the problem under the field and moving focus to it. Once there is one, the card is added to the block's list and the wall draws it before the five drawn cards: pinned notes come first, then the newest. The card shows its label with its glyph, a pin when it is pinned, the title and up to four lines of the text, and the reminder day when there is one. A polite message says what was saved, and the count in the header follows the cards. Reopening the dialog starts from an empty note.
How does the reminder day work, and does anything ring?
Nothing rings. The reminder is a day kept on the card. The Reminder button opens a calendar in the same space as the note's fields, and focus moves to its title so a keyboard user starts at the top; choosing a day, Clear or No reminder goes back to the note with focus on the Reminder button, and Back to the note leaves it as it was. Days before AS_OF, the date the demo treats as today, are closed, and the dates are printed from fixed ISO days, never from your clock. In your app schedule the reminder on your server when the note is saved.
What does the 280 limit do?
The field stops at 280 characters and the count under it, such as 42 of 280, is for the eye: it is hidden from screen readers, so typing is not interrupted. The textarea has a fixed height of about four lines and scrolls inside, so the dialog keeps its size however much you write. The title stops at 60 characters.
What stays local in the demo, and how do I wire it up?
Everything. The notes live in this page's state and are gone on a reload; nothing is stored, sent or scheduled. In your app send the note from save, keep the list in your own state or on your server, and load the wall's own cards from your API in place of the five drawn ones.
Is it accessible from the keyboard?
Yes. The real dialog is named New note, focus starts in the title and stays inside until it closes, and Escape and the close button return focus to the New note button. The labels are a group named Label with arrow-key movement, the Pin to top switch is named by its text, and the calendar is the catalog's own with arrow keys between days. 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; Escape inside it and its close button close it and put focus on the button.
Related
- Pro
Quick Reply Dialog
Pickers and searchA helpdesk ticket with its saved-replies dialog shown open: a searchable list of eight replies, a preview filled from the ticket, a flag and a field for each variable it cannot fill, an SMS character count and an Insert reply button that writes into the composer.
- Pro
Set Reminder Dialog
Time and schedulingA to-do list with its reminder dialog shown open: five quick chips, an inline calendar and a time in quarter hours, repeat and notify choices, and one plain sentence that always reads the choice back.
- Pro
An inventory table with a side sheet that edits one item and steps through the rest: name, SKU, quantity, bin, reorder level and notes, an error summary with links, a change line with Reset, and Save and next.
- Pro
Select Template Dialog
Pickers and searchA documents app's new-document dialog shown open: six icon tiles in two columns that move with the arrow keys and jump on a typed letter, Popular and New badges, a Create button that names the choice, and the new file landing on the home.
- Pro
Media Upload Dialog
Media and widgetsA video library with its upload dialog shown open: a drop zone for images, video and audio that names the files it turns away and why, tiles for the ones that pass with a check each, bulk removal, a total and an Add button that puts the clips in the library.
- Pro
Merge Accounts Dialog
Notes and editingA contacts page with its merge dialog shown open: two accounts that look like one person in a table, matching fields marked Same, a radio in each cell where they differ, a Result column that follows your choices, and Merge accounts waiting until every conflict is chosen.