KQ-1348 · NOTES/APP

Notes App

A complete notes screen built around block-editor, pin-press and bin-lid: tags whose current pill travels on snap, a list whose pinned note lifts on snap and glides to the top — under a Pinned heading or floated over the rest — while the rows between close the gap on glide, search that washes the words it found and grows from its magnifier on snap, and an editor that cross-fades in from 4px on glide with the note's own title and tags over the blocks. Deleting drops the note in the bin until its undo ring drains. Below 640px the list and the note become a stack whose pushes slide on glide and whose left edge takes a 1:1 back-swipe that commits by projection; the list is one tab stop with Up, Down, Home and End, slash searches, and Escape clears the search or goes back.

KQ-1348 · NOTES/APP

All notes7 notes

  • Pinned

  • Notes

Edited 09:12 · 82 words

Moves it to the bin, with 4 seconds to undo.
  • #field
  • #survey

North basin survey, day 2

Fieldline · shared with the survey team

8 blocks · 82 words

Alt+Up or Alt+Down moves the block. Type / for block types. Select text for formatting, or press Alt+F10 to reach it.

Down from the search reaches the notes; Up and Down move between them and Enter opens one. Slash searches from anywhere.

all notes · 7 notes · 2 pinned

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/notes-app

Props

pin
"section" | "float" | "off"
default "section"
Where pinned notes go: under a Pinned heading, floated to the top of one list with a pin glyph, or pinning is off (no pin button, plain recency order).
search
"field" | "expand" | "off"
default "field"
How search lives over the list: an open field, a magnifier that grows into the field and folds back when emptied and left, or no search.
density
"compact" | "cozy" | "roomy"
default "cozy"
Row height and how much each row says: title and date, one snippet line, or two lines and the tags.
notes / defaultNotes
NoteRecord[]
default defaultNotes
Every note: title, block-editor blocks, tags, pinned and when it was last edited.
onNotesChange
(notes: NoteRecord[]) => void
default —
Fires from the edit, pin, tag, creation or deletion that changed the notes, with all of them.
note / defaultNote
string | null
default the most recently edited
The open note's id.
onNoteChange
(id: string | null) => void
default —
Fires from the row, the new note or the deletion that changed the open note.
tag / defaultTag
string | null
default null
The tag the list is filtered to, or null for every note.
onTagChange
(tag: string | null) => void
default —
Fires from the sidebar row or chip that changed the filter.
query / defaultQuery
string
default ""
The search text; it matches titles, every block and tags.
onQueryChange
(query: string) => void
default —
Fires with every edit of the search field, Clear and Escape.
now
Date | number
default defaultNotesNow
The moment dates are read against, and what an edit is stamped with. Never read from the clock during render.
zoneOffset
number
default 0
Minutes east of UTC that times are shown in, so server and browser agree.
onCreate
(note: NoteRecord) => void
default —
A new note was made; it is already in the list and open with its title focused.
onDelete
(note: NoteRecord) => void
default —
A note was thrown away, once its undo window ran out.
onPinChange
(id: string, pinned: boolean) => void
default —
The editor's pin was pressed.
status
"ready" | "loading" | "error"
default "ready"
Loading draws placeholder rows and lines; error offers Try again.
onRetry
() => void
default —
Try again was pressed in the error state.
label
string
default "Notes"
The screen's accessible name.
sound
boolean
default false
Play a tick for list steps and tag picks and a click for new notes, tags and screen moves; the composed pieces play their own. Off unless asked for.
disabled
boolean
default false
Read only: nothing can be written, pinned, tagged or deleted.
className
string
default —
Classes for the root. It is 560px tall by default; pass a height class to change it.