side-notes/openspec/changes/sidepanel-ux-improvements/specs/note-editor/spec.md

69 lines
5 KiB
Markdown

## ADDED Requirements
### Requirement: Editor focused on panel open with restored caret
WHEN the side panel opens, the system SHALL place input focus in the note editor and restore the caret to the position last saved for that note, including the editor's scroll offset. Restoration also applies when the panel switches to a different tab's note or reloads after navigation. If the saved position exceeds the current content length (e.g., the note was edited elsewhere), it SHALL be clamped to a valid offset. Notes saved before this feature have no stored position and SHALL restore to the start of the note.
#### Scenario: Panel opens with caret where the user left it
- **WHEN** a user edits a note, moves the caret to a specific position, closes the panel, and reopens it on the same page
- **THEN** the editor has focus and the caret is at the last saved position with the same scroll offset
#### Scenario: Switching tabs restores that note's caret
- **WHEN** a user switches to a different tab whose note has a saved caret position
- **THEN** the panel shows the new tab's note with its own saved caret position restored
#### Scenario: Saved position beyond current content is clamped
- **WHEN** a note's content was shortened in another panel after the caret position was saved
- **THEN** the caret is restored at the end of the current content rather than an invalid offset
#### Scenario: Legacy note without a saved position
- **WHEN** a user opens a note that was saved before caret persistence existed
- **THEN** the editor has focus with the caret at the start of the note and no error occurs
### Requirement: Caret position saved continuously
The system SHALL save the caret position (and editor scroll offset) as part of every autosave, SHALL also persist caret-only movement (selection changes without content edits) after a short debounce, and SHALL flush any unsaved caret position when the editor loses focus or the panel is hidden.
#### Scenario: Caret saved with content autosave
- **WHEN** a user types in the editor and the autosave completes
- **THEN** the stored note record includes the caret position and scroll offset at save time
#### Scenario: Caret-only movement is persisted
- **WHEN** a user moves the caret without typing and then closes the panel
- **THEN** the last caret position has been persisted and is restored on the next open
### Requirement: Caret-only remote saves do not disturb other panels
WHEN the same note is open in more than one panel and a remote panel persists only a caret/scroll update (content unchanged), other panels SHALL NOT reload the editor content or move their own caret. Content-changing remote saves keep the existing refresh behavior (reload immediately, or defer until blur when the local editor is focused).
#### Scenario: Remote caret save leaves local caret untouched
- **WHEN** a note open in tab A persists a caret-only update and the same note is open in tab B
- **THEN** tab B's editor content and caret position remain unchanged
#### Scenario: Remote content save still refreshes
- **WHEN** a note open in tab A saves changed content and the same note is open in tab B without editor focus
- **THEN** tab B's panel updates to show the content saved from tab A
### Requirement: Adjustable editor font size
The editor SHALL render note text in a monospace font at a user-adjustable size, defaulting to 16px when no preference is stored. The size SHALL be changeable via decrease/increase controls in the panel header adjacent to the notes-list button, and via keyboard shortcuts (increase: `Ctrl+=`/`Cmd+=`, decrease: `Ctrl+-`/`Cmd+-`, reset to default: `Ctrl+0`/`Cmd+0`). The size SHALL be clamped to a bounded range (minimum 10px, maximum 24px, step 1px) and persisted in local storage so it applies to subsequent panel sessions.
#### Scenario: Default size for new users
- **WHEN** a user opens the side panel with no stored font-size preference
- **THEN** the editor text renders at 16px in a monospace font
#### Scenario: Increase and decrease via header controls
- **WHEN** a user clicks the font-size increase control, then the decrease control
- **THEN** the editor font size grows by one step, then returns to its previous size
#### Scenario: Keyboard shortcuts adjust the size
- **WHEN** the user presses `Ctrl+=` and later `Ctrl+-` while the panel is focused
- **THEN** the editor font size increases by one step, then decreases by one step, and the browser's page zoom is not triggered
#### Scenario: Reset shortcut restores the default
- **WHEN** a user has changed the font size and presses `Ctrl+0`
- **THEN** the editor font size returns to 16px
#### Scenario: Size is clamped at the bounds
- **WHEN** a user repeatedly decreases the font size below the minimum or increases it above the maximum
- **THEN** the size stops at the bound and the control remains usable in the opposite direction
#### Scenario: Size persists across sessions
- **WHEN** a user changes the font size, closes the panel, and reopens it later
- **THEN** the editor renders at the previously chosen size